[Scummvm-git-logs] scummvm master -> 5956fa4757fe303fdaeb386f637ec27590a5a5fc
sev-
noreply at scummvm.org
Wed Apr 5 10:45:22 UTC 2023
This automated email contains information about 11 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
78faa2ae28 IMAGE: Defer creation of surface until decodeFrame() is called in Indeo codecs
9a6897a852 IMAGE: Allow the default pixel format to be changed for YUV codecs
8a4a5bdc55 VIDEO: Add setOutputPixelFormat() to the VideoDecoder interface
a5603ac1f4 TESTBED: Pick the best pixel format in the video player
d72fee204c VIDEO: Implement setOutputPixelFormat() for MPEGPSDecoder
adef12d993 VIDEO: Implement setOutputPixelFormat() for BinkDecoder
475354cb4c VIDEO: Implement setOutputPixelFormat() for PSXStreamDecoder
70a6159af5 VIDEO: Implement setOutputPixelFormat() for TheoraDecoder
e6260bf089 VIDEO: Implement setOutputPixelFormat() for MKVDecoder
75e8dd71b7 ASYLUM: Select the best pixel format for video playback
5956fa4757 VIDEO: Remove VideoDecoder::setDefaultHighColorFormat()
Commit: 78faa2ae2888a0b4645490b1cdb77bb27173bebb
https://github.com/scummvm/scummvm/commit/78faa2ae2888a0b4645490b1cdb77bb27173bebb
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-04-05T12:45:13+02:00
Commit Message:
IMAGE: Defer creation of surface until decodeFrame() is called in Indeo codecs
Changed paths:
image/codecs/indeo/indeo.cpp
image/codecs/indeo/indeo.h
image/codecs/indeo3.cpp
image/codecs/indeo3.h
image/codecs/indeo4.cpp
image/codecs/indeo5.cpp
diff --git a/image/codecs/indeo/indeo.cpp b/image/codecs/indeo/indeo.cpp
index 6dbafe0e0b5..997b16a3c13 100644
--- a/image/codecs/indeo/indeo.cpp
+++ b/image/codecs/indeo/indeo.cpp
@@ -463,7 +463,10 @@ IVI45DecContext::IVI45DecContext() : _gb(nullptr), _frameNum(0), _frameType(0),
/*------------------------------------------------------------------------*/
-IndeoDecoderBase::IndeoDecoderBase(uint16 width, uint16 height, uint bitsPerPixel) : Codec() {
+IndeoDecoderBase::IndeoDecoderBase(uint16 width, uint16 height, uint bitsPerPixel) : Codec(), _surface(nullptr) {
+ _width = width;
+ _height = height;
+ _bitsPerPixel = bitsPerPixel;
_pixelFormat = g_system->getScreenFormat();
if (_pixelFormat.bytesPerPixel == 1) {
@@ -486,13 +489,15 @@ IndeoDecoderBase::IndeoDecoderBase(uint16 width, uint16 height, uint bitsPerPixe
}
}
- _surface.create(width, height, _pixelFormat);
- _surface.fillRect(Common::Rect(0, 0, width, height), (bitsPerPixel == 32) ? 0xff : 0);
_ctx._bRefBuf = 3; // buffer 2 is used for scalability mode
}
IndeoDecoderBase::~IndeoDecoderBase() {
- _surface.free();
+ if (_surface) {
+ _surface->free();
+ delete _surface;
+ _surface = nullptr;
+ }
IVIPlaneDesc::freeBuffers(_ctx._planes);
if (_ctx._mbVlc._custTab._table)
_ctx._mbVlc._custTab.freeVlc();
@@ -507,6 +512,12 @@ int IndeoDecoderBase::decodeIndeoFrame() {
AVFrame frameData;
AVFrame *frame = &frameData;
+ if (!_surface) {
+ _surface = new Graphics::Surface;
+ _surface->create(_width, _height, _pixelFormat);
+ _surface->fillRect(Common::Rect(0, 0, _width, _height), (_bitsPerPixel == 32) ? 0xff : 0);
+ }
+
// Decode the header
if (decodePictureHeader() < 0)
return -1;
@@ -562,7 +573,7 @@ int IndeoDecoderBase::decodeIndeoFrame() {
if (!isNonNullFrame())
return 0;
- assert(_ctx._planes[0]._width <= _surface.w && _ctx._planes[0]._height <= _surface.h);
+ assert(_ctx._planes[0]._width <= _surface->w && _ctx._planes[0]._height <= _surface->h);
result = frame->setDimensions(_ctx._planes[0]._width, _ctx._planes[0]._height);
if (result < 0)
return result;
@@ -583,7 +594,7 @@ int IndeoDecoderBase::decodeIndeoFrame() {
outputPlane(&_ctx._planes[1], frame->_data[2], frame->_linesize[2]);
// Merge the planes into the final surface
- YUVToRGBMan.convert410(&_surface, Graphics::YUVToRGBManager::kScaleITU,
+ YUVToRGBMan.convert410(_surface, Graphics::YUVToRGBManager::kScaleITU,
frame->_data[0], frame->_data[1], frame->_data[2], frame->_width, frame->_height,
frame->_width, frame->_width);
diff --git a/image/codecs/indeo/indeo.h b/image/codecs/indeo/indeo.h
index 639d7f19023..388ea46004e 100644
--- a/image/codecs/indeo/indeo.h
+++ b/image/codecs/indeo/indeo.h
@@ -518,8 +518,11 @@ private:
int blkSize);
protected:
IVI45DecContext _ctx;
+ uint16 _width;
+ uint16 _height;
+ uint _bitsPerPixel;
Graphics::PixelFormat _pixelFormat;
- Graphics::Surface _surface;
+ Graphics::Surface *_surface;
/**
* Scan patterns shared between indeo4 and indeo5
diff --git a/image/codecs/indeo3.cpp b/image/codecs/indeo3.cpp
index f7918653d54..ca43d803cc6 100644
--- a/image/codecs/indeo3.cpp
+++ b/image/codecs/indeo3.cpp
@@ -39,10 +39,12 @@
namespace Image {
-Indeo3Decoder::Indeo3Decoder(uint16 width, uint16 height, uint bitsPerPixel) : _ModPred(0), _corrector_type(0) {
+Indeo3Decoder::Indeo3Decoder(uint16 width, uint16 height, uint bitsPerPixel) : _surface(nullptr), _ModPred(0), _corrector_type(0) {
_iv_frame[0].the_buf = 0;
_iv_frame[1].the_buf = 0;
+ _width = width;
+ _height = height;
_pixelFormat = g_system->getScreenFormat();
if (_pixelFormat.bytesPerPixel == 1) {
@@ -65,16 +67,16 @@ Indeo3Decoder::Indeo3Decoder(uint16 width, uint16 height, uint bitsPerPixel) : _
}
}
- _surface = new Graphics::Surface;
- _surface->create(width, height, _pixelFormat);
-
buildModPred();
allocFrames();
}
Indeo3Decoder::~Indeo3Decoder() {
- _surface->free();
- delete _surface;
+ if (_surface) {
+ _surface->free();
+ delete _surface;
+ _surface = nullptr;
+ }
delete[] _iv_frame[0].the_buf;
delete[] _ModPred;
@@ -134,8 +136,8 @@ void Indeo3Decoder::buildModPred() {
}
void Indeo3Decoder::allocFrames() {
- int32 luma_width = (_surface->w + 3) & (~3);
- int32 luma_height = (_surface->h + 3) & (~3);
+ int32 luma_width = (_width + 3) & (~3);
+ int32 luma_height = (_height + 3) & (~3);
int32 chroma_width = ((luma_width >> 2) + 3) & (~3);
int32 chroma_height = ((luma_height >> 2) + 3) & (~3);
@@ -211,6 +213,11 @@ const Graphics::Surface *Indeo3Decoder::decodeFrame(Common::SeekableReadStream &
_ref_frame = _iv_frame + 1;
}
+ if (!_surface) {
+ _surface = new Graphics::Surface;
+ _surface->create(_width, _height, _pixelFormat);
+ }
+
if (flags3 == 0x80)
return _surface;
diff --git a/image/codecs/indeo3.h b/image/codecs/indeo3.h
index d27b007f715..2646f8fcea6 100644
--- a/image/codecs/indeo3.h
+++ b/image/codecs/indeo3.h
@@ -56,6 +56,8 @@ public:
private:
Graphics::Surface *_surface;
+ uint16 _width;
+ uint16 _height;
Graphics::PixelFormat _pixelFormat;
static const int _corrector_type_0[24];
diff --git a/image/codecs/indeo4.cpp b/image/codecs/indeo4.cpp
index d8b4ba714d6..32c4583b213 100644
--- a/image/codecs/indeo4.cpp
+++ b/image/codecs/indeo4.cpp
@@ -88,7 +88,7 @@ const Graphics::Surface *Indeo4Decoder::decodeFrame(Common::SeekableReadStream &
_ctx._frameData = nullptr;
_ctx._frameSize = 0;
- return (err < 0) ? nullptr : &_surface;
+ return (err < 0) ? nullptr : _surface;
}
int Indeo4Decoder::decodePictureHeader() {
@@ -111,11 +111,11 @@ int Indeo4Decoder::decodePictureHeader() {
_ctx._hasBFrames = true;
_ctx._hasTransp = _ctx._gb->getBit();
- if (_ctx._hasTransp && _surface.format.aBits() == 0) {
+ if (_ctx._hasTransp && _surface->format.aBits() == 0) {
// Surface is 4 bytes per pixel, but only RGB. So promote the
// surface to full RGBA, and convert all the existing pixels
_pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
- _surface.convertToInPlace(_pixelFormat);
+ _surface->convertToInPlace(_pixelFormat);
}
// unknown bit: Mac decoder ignores this bit, XANIM returns error
@@ -610,16 +610,16 @@ int Indeo4Decoder::decodeRLETransparency(VLC_TYPE (*table)[2]) {
bool runIsOpaque = _ctx._gb->getBit();
bool nextRunIsOpaque = !runIsOpaque;
- uint32 *pixel = (uint32 *)_surface.getPixels();
- const int surfacePixelPitch = _surface.pitch / _surface.format.bytesPerPixel;
- const int surfacePadding = surfacePixelPitch - _surface.w;
- const uint32 *endOfVisibleRow = pixel + _surface.w;
- const uint32 *endOfVisibleArea = pixel + surfacePixelPitch * _surface.h - surfacePadding;
+ uint32 *pixel = (uint32 *)_surface->getPixels();
+ const int surfacePixelPitch = _surface->pitch / _surface->format.bytesPerPixel;
+ const int surfacePadding = surfacePixelPitch - _surface->w;
+ const uint32 *endOfVisibleRow = pixel + _surface->w;
+ const uint32 *endOfVisibleArea = pixel + surfacePixelPitch * _surface->h - surfacePadding;
- const int codecAlignedWidth = (_surface.w + 31) & ~31;
- const int codecPaddingSize = codecAlignedWidth - _surface.w;
+ const int codecAlignedWidth = (_surface->w + 31) & ~31;
+ const int codecPaddingSize = codecAlignedWidth - _surface->w;
- int numPixelsToRead = codecAlignedWidth * _surface.h;
+ int numPixelsToRead = codecAlignedWidth * _surface->h;
int numPixelsToSkip = 0;
while (numPixelsToRead > 0) {
int value = _ctx._gb->getVLC2<1, IVI_VLC_BITS>(table);
@@ -716,7 +716,7 @@ int Indeo4Decoder::decodeTransparency() {
if (_ctx._gb->getBit()) { /* @350 */
/* @358 */
- _ctx._transKeyColor = _surface.format.ARGBToColor(0, _ctx._gb->getBits<8>(), _ctx._gb->getBits<8>(), _ctx._gb->getBits<8>());
+ _ctx._transKeyColor = _surface->format.ARGBToColor(0, _ctx._gb->getBits<8>(), _ctx._gb->getBits<8>(), _ctx._gb->getBits<8>());
debug(4, "Indeo4: Key color is %08x", _ctx._transKeyColor);
/* @477 */
}
@@ -767,8 +767,8 @@ int Indeo4Decoder::decodeTransparency() {
// necessary for correct decoding of game videos.
assert(!_ctx._usesTiling);
- assert(_surface.format.bytesPerPixel == 4);
- assert((_surface.pitch % 4) == 0);
+ assert(_surface->format.bytesPerPixel == 4);
+ assert((_surface->pitch % 4) == 0);
const uint32 startByte = _ctx._gb->pos() / 8;
@@ -781,7 +781,7 @@ int Indeo4Decoder::decodeTransparency() {
// It should only be necessary to draw transparency here since the
// data from the YUV planes gets drawn to the output surface on each
// frame, which resets the surface pixels to be fully opaque
- _surface.fillRect(Common::Rect(_surface.w, _surface.h), _ctx._transKeyColor);
+ _surface->fillRect(Common::Rect(_surface->w, _surface->h), _ctx._transKeyColor);
}
// No alignment here
diff --git a/image/codecs/indeo5.cpp b/image/codecs/indeo5.cpp
index ab45cd9d041..c845b189641 100644
--- a/image/codecs/indeo5.cpp
+++ b/image/codecs/indeo5.cpp
@@ -96,7 +96,7 @@ const Graphics::Surface *Indeo5Decoder::decodeFrame(Common::SeekableReadStream &
_ctx._frameData = nullptr;
_ctx._frameSize = 0;
- return (err < 0) ? nullptr : &_surface;
+ return (err < 0) ? nullptr : _surface;
}
int Indeo5Decoder::decodePictureHeader() {
Commit: 9a6897a85273e64ae46c03e932cc771625de0b58
https://github.com/scummvm/scummvm/commit/9a6897a85273e64ae46c03e932cc771625de0b58
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-04-05T12:45:13+02:00
Commit Message:
IMAGE: Allow the default pixel format to be changed for YUV codecs
Changed paths:
image/codecs/cinepak.cpp
image/codecs/cinepak.h
image/codecs/codec.h
image/codecs/indeo/indeo.cpp
image/codecs/indeo/indeo.h
image/codecs/indeo3.cpp
image/codecs/indeo3.h
image/codecs/mjpeg.cpp
image/codecs/mjpeg.h
image/codecs/mpeg.cpp
image/codecs/mpeg.h
image/codecs/svq1.cpp
image/codecs/svq1.h
image/codecs/xan.h
image/jpeg.h
diff --git a/image/codecs/cinepak.cpp b/image/codecs/cinepak.cpp
index 53d68617451..1133eccd731 100644
--- a/image/codecs/cinepak.cpp
+++ b/image/codecs/cinepak.cpp
@@ -624,6 +624,14 @@ void CinepakDecoder::decodeVectors(Common::SeekableReadStream &stream, uint16 st
}
}
+bool CinepakDecoder::setOutputPixelFormat(const Graphics::PixelFormat &format) {
+ if (_bitsPerPixel == 8)
+ return false;
+
+ _pixelFormat = format;
+ return true;
+}
+
bool CinepakDecoder::canDither(DitherType type) const {
return (type == kDitherTypeVFW || type == kDitherTypeQT) && _bitsPerPixel == 24;
}
diff --git a/image/codecs/cinepak.h b/image/codecs/cinepak.h
index 2c67b194c5f..a537ac8c3c5 100644
--- a/image/codecs/cinepak.h
+++ b/image/codecs/cinepak.h
@@ -74,6 +74,7 @@ public:
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream) override;
Graphics::PixelFormat getPixelFormat() const override { return _pixelFormat; }
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format) override;
bool containsPalette() const override { return _ditherPalette != 0; }
const byte *getPalette() override { _dirtyPalette = false; return _ditherPalette; }
diff --git a/image/codecs/codec.h b/image/codecs/codec.h
index 7645039c7f5..8109c50766d 100644
--- a/image/codecs/codec.h
+++ b/image/codecs/codec.h
@@ -85,6 +85,12 @@ public:
*/
virtual Graphics::PixelFormat getPixelFormat() const = 0;
+ /**
+ * Select the preferred format to use, for codecs where this is faster than converting
+ * the image afterwards. Returns true if supported, and false otherwise.
+ */
+ virtual bool setOutputPixelFormat(const Graphics::PixelFormat &format) { return false; }
+
/**
* Can this codec's frames contain a palette?
*/
diff --git a/image/codecs/indeo/indeo.cpp b/image/codecs/indeo/indeo.cpp
index 997b16a3c13..aa307906fa7 100644
--- a/image/codecs/indeo/indeo.cpp
+++ b/image/codecs/indeo/indeo.cpp
@@ -469,25 +469,9 @@ IndeoDecoderBase::IndeoDecoderBase(uint16 width, uint16 height, uint bitsPerPixe
_bitsPerPixel = bitsPerPixel;
_pixelFormat = g_system->getScreenFormat();
- if (_pixelFormat.bytesPerPixel == 1) {
- switch (bitsPerPixel) {
- case 15:
- _pixelFormat = Graphics::PixelFormat(2, 5, 5, 5, 0, 0, 5, 10, 0);
- break;
- case 16:
- _pixelFormat = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
- break;
- case 24:
- _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 0);
- break;
- case 32:
- _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
- break;
- default:
- error("Invalid color depth");
- break;
- }
- }
+ // 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);
_ctx._bRefBuf = 3; // buffer 2 is used for scalability mode
}
diff --git a/image/codecs/indeo/indeo.h b/image/codecs/indeo/indeo.h
index 388ea46004e..dc543e74ad5 100644
--- a/image/codecs/indeo/indeo.h
+++ b/image/codecs/indeo/indeo.h
@@ -536,6 +536,12 @@ protected:
*/
Graphics::PixelFormat getPixelFormat() const override { return _pixelFormat; }
+ /**
+ * Select the preferred format to use, for codecs where this is faster than converting
+ * the image afterwards. Returns true if supported, and false otherwise.
+ */
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format) { _pixelFormat = format; return true; }
+
/**
* Decode the Indeo picture header.
* @returns 0 = Ok, negative number = error
diff --git a/image/codecs/indeo3.cpp b/image/codecs/indeo3.cpp
index ca43d803cc6..dc5f31886ee 100644
--- a/image/codecs/indeo3.cpp
+++ b/image/codecs/indeo3.cpp
@@ -47,25 +47,9 @@ Indeo3Decoder::Indeo3Decoder(uint16 width, uint16 height, uint bitsPerPixel) : _
_height = height;
_pixelFormat = g_system->getScreenFormat();
- if (_pixelFormat.bytesPerPixel == 1) {
- switch (bitsPerPixel) {
- case 15:
- _pixelFormat = Graphics::PixelFormat(2, 5, 5, 5, 0, 0, 5, 10, 0);
- break;
- case 16:
- _pixelFormat = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
- break;
- case 24:
- _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 0);
- break;
- case 32:
- _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
- break;
- default:
- error("Invalid color depth");
- break;
- }
- }
+ // 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);
buildModPred();
allocFrames();
diff --git a/image/codecs/indeo3.h b/image/codecs/indeo3.h
index 2646f8fcea6..d223c1b3de6 100644
--- a/image/codecs/indeo3.h
+++ b/image/codecs/indeo3.h
@@ -50,6 +50,7 @@ public:
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream) override;
Graphics::PixelFormat getPixelFormat() const override;
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format) override { _pixelFormat = format; return true; }
static bool isIndeo3(Common::SeekableReadStream &stream);
diff --git a/image/codecs/mjpeg.cpp b/image/codecs/mjpeg.cpp
index 662bee3b8d7..397553e6366 100644
--- a/image/codecs/mjpeg.cpp
+++ b/image/codecs/mjpeg.cpp
@@ -40,6 +40,11 @@ namespace Image {
MJPEGDecoder::MJPEGDecoder() : Codec() {
_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);
+
_surface = 0;
}
diff --git a/image/codecs/mjpeg.h b/image/codecs/mjpeg.h
index c52b38144ec..c68ecc0d85e 100644
--- a/image/codecs/mjpeg.h
+++ b/image/codecs/mjpeg.h
@@ -47,6 +47,7 @@ public:
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream) override;
Graphics::PixelFormat getPixelFormat() const override { return _pixelFormat; }
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format) override { _pixelFormat = format; return true; }
private:
Graphics::PixelFormat _pixelFormat;
diff --git a/image/codecs/mpeg.cpp b/image/codecs/mpeg.cpp
index d10eff0fd38..c708bd3ee3e 100644
--- a/image/codecs/mpeg.cpp
+++ b/image/codecs/mpeg.cpp
@@ -37,6 +37,11 @@ namespace Image {
MPEGDecoder::MPEGDecoder() : Codec() {
_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);
+
_surface = 0;
_mpegDecoder = mpeg2_init();
diff --git a/image/codecs/mpeg.h b/image/codecs/mpeg.h
index eb7a64af597..5b5eaf50de4 100644
--- a/image/codecs/mpeg.h
+++ b/image/codecs/mpeg.h
@@ -53,6 +53,7 @@ public:
// Codec interface
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream) override;
Graphics::PixelFormat getPixelFormat() const override { return _pixelFormat; }
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format) override { _pixelFormat = format; return true; }
// MPEGPSDecoder call
bool decodePacket(Common::SeekableReadStream &packet, uint32 &framePeriod, Graphics::Surface *dst = 0);
diff --git a/image/codecs/svq1.cpp b/image/codecs/svq1.cpp
index c02c5f22e09..47dde72bf7c 100644
--- a/image/codecs/svq1.cpp
+++ b/image/codecs/svq1.cpp
@@ -47,6 +47,12 @@ SVQ1Decoder::SVQ1Decoder(uint16 width, uint16 height) {
debug(1, "SVQ1Decoder::SVQ1Decoder(width:%d, height:%d)", width, height);
_width = width;
_height = height;
+ _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);
+
_frameWidth = _frameHeight = 0;
_surface = 0;
@@ -251,7 +257,7 @@ const Graphics::Surface *SVQ1Decoder::decodeFrame(Common::SeekableReadStream &st
// Now we'll create the surface
if (!_surface) {
_surface = new Graphics::Surface();
- _surface->create(yWidth, yHeight, g_system->getScreenFormat());
+ _surface->create(yWidth, yHeight, _pixelFormat);
_surface->w = _width;
_surface->h = _height;
}
diff --git a/image/codecs/svq1.h b/image/codecs/svq1.h
index e9c678f38ba..f5090c27f7b 100644
--- a/image/codecs/svq1.h
+++ b/image/codecs/svq1.h
@@ -44,9 +44,11 @@ public:
~SVQ1Decoder() override;
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream) override;
- Graphics::PixelFormat getPixelFormat() const override { return _surface->format; }
+ Graphics::PixelFormat getPixelFormat() const override { return _pixelFormat; }
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format) override { _pixelFormat = format; return true; }
private:
+ Graphics::PixelFormat _pixelFormat;
Graphics::Surface *_surface;
uint16 _width, _height;
uint16 _frameWidth, _frameHeight;
diff --git a/image/codecs/xan.h b/image/codecs/xan.h
index 8f9efcfb0c6..513fd748c1f 100644
--- a/image/codecs/xan.h
+++ b/image/codecs/xan.h
@@ -47,6 +47,7 @@ public:
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream) override;
Graphics::PixelFormat getPixelFormat() const override { return _pixelFormat; }
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format) override { _pixelFormat = format; return true; }
private:
void decodeFrameType0(Common::SeekableReadStream &stream);
diff --git a/image/jpeg.h b/image/jpeg.h
index 9dcb46f899b..26b9a87a6c1 100644
--- a/image/jpeg.h
+++ b/image/jpeg.h
@@ -59,6 +59,7 @@ public:
// Codec API
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream) override;
Graphics::PixelFormat getPixelFormat() const override;
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format) override { _requestedPixelFormat = format; return true; }
// Special API for JPEG
enum ColorSpace {
@@ -95,13 +96,6 @@ public:
*/
void setOutputColorSpace(ColorSpace outSpace) { _colorSpace = outSpace; }
- /**
- * Request the output pixel format. The JPEG decoder provides high performance
- * color conversion routines for some pixel formats. This setting allows to use
- * them and avoid costly subsequent color conversion.
- */
- void setOutputPixelFormat(const Graphics::PixelFormat &format) { _requestedPixelFormat = format; }
-
private:
Graphics::Surface _surface;
ColorSpace _colorSpace;
Commit: 8a4a5bdc55c00ffadb84e5d1d7f8bfd8d7502340
https://github.com/scummvm/scummvm/commit/8a4a5bdc55c00ffadb84e5d1d7f8bfd8d7502340
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-04-05T12:45:13+02:00
Commit Message:
VIDEO: Add setOutputPixelFormat() to the VideoDecoder interface
Changed paths:
video/3do_decoder.cpp
video/3do_decoder.h
video/avi_decoder.cpp
video/avi_decoder.h
video/hnm_decoder.cpp
video/hnm_decoder.h
video/qt_decoder.cpp
video/qt_decoder.h
video/video_decoder.cpp
video/video_decoder.h
diff --git a/video/3do_decoder.cpp b/video/3do_decoder.cpp
index 7cee1adf88c..8efe5786757 100644
--- a/video/3do_decoder.cpp
+++ b/video/3do_decoder.cpp
@@ -396,6 +396,10 @@ Graphics::PixelFormat ThreeDOMovieDecoder::StreamVideoTrack::getPixelFormat() co
return _codec->getPixelFormat();
}
+bool ThreeDOMovieDecoder::StreamVideoTrack::setOutputPixelFormat(const Graphics::PixelFormat &format) {
+ return _codec->setOutputPixelFormat(format);
+}
+
void ThreeDOMovieDecoder::StreamVideoTrack::decodeFrame(Common::SeekableReadStream *stream, uint32 videoTimeStamp) {
_surface = _codec->decodeFrame(*stream);
_curFrame++;
diff --git a/video/3do_decoder.h b/video/3do_decoder.h
index fa3034e3d17..e6936aff0b9 100644
--- a/video/3do_decoder.h
+++ b/video/3do_decoder.h
@@ -75,6 +75,7 @@ private:
uint16 getWidth() const override { return _width; }
uint16 getHeight() const override { return _height; }
Graphics::PixelFormat getPixelFormat() const override;
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format);
int getCurFrame() const override { return _curFrame; }
int getFrameCount() const override { return _frameCount; }
void setNextFrameStartTime(uint32 nextFrameStartTime) { _nextFrameStartTime = nextFrameStartTime; }
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp
index 3a589c5fd55..872b5370414 100644
--- a/video/avi_decoder.cpp
+++ b/video/avi_decoder.cpp
@@ -985,6 +985,13 @@ Graphics::PixelFormat AVIDecoder::AVIVideoTrack::getPixelFormat() const {
return Graphics::PixelFormat();
}
+bool AVIDecoder::AVIVideoTrack::setOutputPixelFormat(const Graphics::PixelFormat &format) {
+ if (_videoCodec)
+ return _videoCodec->setOutputPixelFormat(format);
+
+ return false;
+}
+
void AVIDecoder::AVIVideoTrack::loadPaletteFromChunkRaw(Common::SeekableReadStream *chunk, int firstEntry, int numEntries) {
assert(chunk);
assert(firstEntry >= 0);
diff --git a/video/avi_decoder.h b/video/avi_decoder.h
index 0b6bdda7652..1e3f00693f2 100644
--- a/video/avi_decoder.h
+++ b/video/avi_decoder.h
@@ -212,6 +212,7 @@ protected:
uint16 getHeight() const { return _bmInfo.height; }
uint16 getBitCount() const { return _bmInfo.bitCount; }
Graphics::PixelFormat getPixelFormat() const;
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format);
int getCurFrame() const { return _curFrame; }
int getFrameCount() const { return _frameCount; }
Common::String &getName() { return _vidsHeader.name; }
diff --git a/video/hnm_decoder.cpp b/video/hnm_decoder.cpp
index 35a2ac53ef5..ebb789da054 100644
--- a/video/hnm_decoder.cpp
+++ b/video/hnm_decoder.cpp
@@ -1064,6 +1064,10 @@ Graphics::PixelFormat HNMDecoder::HNM6VideoTrack::getPixelFormat() const {
return _decoder->getPixelFormat();
}
+bool HNMDecoder::HNM6VideoTrack::setOutputPixelFormat(const Graphics::PixelFormat &format) {
+ return _decoder->setOutputPixelFormat(format);
+}
+
void HNMDecoder::HNM6VideoTrack::decodeChunk(byte *data, uint32 size,
uint16 chunkType, uint16 flags) {
if (chunkType == MKTAG16('I', 'X') ||
diff --git a/video/hnm_decoder.h b/video/hnm_decoder.h
index 29361fbf732..4bd7502e415 100644
--- a/video/hnm_decoder.h
+++ b/video/hnm_decoder.h
@@ -162,6 +162,7 @@ private:
uint16 getWidth() const override;
uint16 getHeight() const override;
Graphics::PixelFormat getPixelFormat() const override;
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format) override;
const Graphics::Surface *decodeNextFrame() override { return _surface; }
virtual void newFrame(uint32 frameDelay) override;
diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp
index 94efc64064a..710fed87882 100644
--- a/video/qt_decoder.cpp
+++ b/video/qt_decoder.cpp
@@ -461,6 +461,13 @@ Graphics::PixelFormat QuickTimeDecoder::VideoTrackHandler::getPixelFormat() cons
return ((VideoSampleDesc *)_parent->sampleDescs[0])->_videoCodec->getPixelFormat();
}
+bool QuickTimeDecoder::VideoTrackHandler::setOutputPixelFormat(const Graphics::PixelFormat &format) {
+ if (_forcedDitherPalette)
+ return false;
+
+ return ((VideoSampleDesc *)_parent->sampleDescs[0])->_videoCodec->setOutputPixelFormat(format);
+}
+
int QuickTimeDecoder::VideoTrackHandler::getFrameCount() const {
return _parent->frameCount;
}
diff --git a/video/qt_decoder.h b/video/qt_decoder.h
index b2364f27c6c..d6766ed8b9e 100644
--- a/video/qt_decoder.h
+++ b/video/qt_decoder.h
@@ -135,6 +135,7 @@ private:
uint16 getWidth() const;
uint16 getHeight() const;
Graphics::PixelFormat getPixelFormat() const;
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format);
int getCurFrame() const { return _curFrame; }
int getFrameCount() const;
uint32 getNextFrameStartTime() const; // milliseconds
diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp
index 28ed9e1ef88..094359df7a9 100644
--- a/video/video_decoder.cpp
+++ b/video/video_decoder.cpp
@@ -48,6 +48,7 @@ VideoDecoder::VideoDecoder() {
_nextVideoTrack = 0;
_mainAudioTrack = 0;
_canSetDither = true;
+ _canSetDefaultFormat = true;
// Find the best format for output
_defaultHighColorFormat = g_system->getScreenFormat();
@@ -79,6 +80,7 @@ void VideoDecoder::close() {
_nextVideoTrack = 0;
_mainAudioTrack = 0;
_canSetDither = true;
+ _canSetDefaultFormat = true;
}
bool VideoDecoder::loadFile(const Common::Path &filename) {
@@ -208,6 +210,7 @@ Graphics::PixelFormat VideoDecoder::getPixelFormat() const {
const Graphics::Surface *VideoDecoder::decodeNextFrame() {
_needsUpdate = false;
_canSetDither = false;
+ _canSetDefaultFormat = false;
readNextPacket();
@@ -547,6 +550,23 @@ bool VideoDecoder::setDitheringPalette(const byte *palette) {
return result;
}
+bool VideoDecoder::setOutputPixelFormat(const Graphics::PixelFormat &format) {
+ // If a frame was already decoded, we can't set it now.
+ if (!_canSetDefaultFormat)
+ return false;
+
+ bool result = false;
+
+ for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++) {
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo) {
+ if (((VideoTrack *)*it)->setOutputPixelFormat(format))
+ result = true;
+ }
+ }
+
+ return result;
+}
+
VideoDecoder::Track::Track() {
_paused = false;
}
diff --git a/video/video_decoder.h b/video/video_decoder.h
index b9adb38772f..6d41dbaafd5 100644
--- a/video/video_decoder.h
+++ b/video/video_decoder.h
@@ -397,6 +397,17 @@ public:
*/
bool setDitheringPalette(const byte *palette);
+ /**
+ * Set the default high color format for videos that convert from YUV.
+ *
+ * This should be called after loadStream(), but before a decodeNextFrame()
+ * call. This is enforced.
+ *
+ * @param format The preferred output pixel format
+ * @return true on success, false otherwise
+ */
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format);
+
/////////////////////////////////////////
// Audio Control
/////////////////////////////////////////
@@ -577,6 +588,11 @@ protected:
*/
virtual Graphics::PixelFormat getPixelFormat() const = 0;
+ /**
+ * Set the default high color format for videos that convert from YUV.
+ */
+ virtual bool setOutputPixelFormat(const Graphics::PixelFormat &format) { return false; }
+
/**
* Get the current frame of this track
*
@@ -954,8 +970,9 @@ private:
mutable bool _dirtyPalette;
const byte *_palette;
- // Enforcement of not being able to set dither
+ // Enforcement of not being able to set dither or set the default format
bool _canSetDither;
+ bool _canSetDefaultFormat;
// Default PixelFormat settings
Graphics::PixelFormat _defaultHighColorFormat;
Commit: a5603ac1f4a26296adf4b4a162ef72378a273230
https://github.com/scummvm/scummvm/commit/a5603ac1f4a26296adf4b4a162ef72378a273230
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-04-05T12:45:13+02:00
Commit Message:
TESTBED: Pick the best pixel format in the video player
Changed paths:
engines/testbed/video.cpp
diff --git a/engines/testbed/video.cpp b/engines/testbed/video.cpp
index f0c43447edd..da349e051c1 100644
--- a/engines/testbed/video.cpp
+++ b/engines/testbed/video.cpp
@@ -52,9 +52,6 @@ Common::Error Videotests::videoTest(const Common::FSNode &node) {
}
Common::Error Videotests::videoTest(Common::SeekableReadStream *stream, const Common::String &name) {
- Graphics::PixelFormat pixelformat = Graphics::PixelFormat::createFormatCLUT8();
- initGraphics(640, 480, &pixelformat);
-
Video::VideoDecoder *video = new Video::QuickTimeDecoder();
if (!video->loadStream(stream)) {
warning("Cannot open video %s", name.c_str());
@@ -63,12 +60,28 @@ Common::Error Videotests::videoTest(Common::SeekableReadStream *stream, const Co
return Common::kReadingFailed;
}
- const byte *palette = video->getPalette();
-
- if (!palette) {
- palette = Video::quickTimeDefaultPalette256;
+ Common::List<Graphics::PixelFormat> supportedFormatsList = g_system->getSupportedFormats();
+ Graphics::PixelFormat pixelformat = supportedFormatsList.front();
+ warning("Best pixel format: %s", pixelformat.toString().c_str());
+ warning("Video pixel format: %s", video->getPixelFormat().toString().c_str());
+
+ if (video->getPixelFormat().isCLUT8()) {
+ pixelformat = Graphics::PixelFormat::createFormatCLUT8();
+ } else {
+ if (pixelformat.isCLUT8() && video->setDitheringPalette(Video::quickTimeDefaultPalette256)) {
+ pixelformat = Graphics::PixelFormat::createFormatCLUT8();
+ } else {
+ pixelformat = supportedFormatsList.front();
+
+ if (!video->setOutputPixelFormat(pixelformat)) {
+ // TODO: Search for the pixel format in supportedFormatsList?
+ pixelformat = video->getPixelFormat();
+ }
+ }
}
- g_system->getPaletteManager()->setPalette(palette, 0, 256);
+
+ warning("Actual pixel format: %s", pixelformat.toString().c_str());
+ initGraphics(640, 480, &pixelformat);
video->start();
@@ -77,20 +90,31 @@ Common::Error Videotests::videoTest(Common::SeekableReadStream *stream, const Co
uint32 pos = video->getTime();
debug(5, "video time: %d", pos);
+ if (pixelformat.isCLUT8() && video->hasDirtyPalette()) {
+ g_system->getPaletteManager()->setPalette(video->getPalette(), 0, 256);
+ }
+
const Graphics::Surface *frame = video->decodeNextFrame();
if (frame) {
- Graphics::Surface *conv = frame->convertTo(pixelformat, 0, 0, palette, 256);
+ const Graphics::Surface *surf = frame;
+ Graphics::Surface *conv = nullptr;
+
+ if (frame->format != pixelformat) {
+ surf = conv = frame->convertTo(pixelformat, video->getPalette());
+ }
int x = 0, y = 0;
- if (conv->w < g_system->getWidth() && conv->h < g_system->getHeight()) {
- x = (g_system->getWidth() - conv->w) >> 1;
- y = (g_system->getHeight() - conv->h) >> 1;
+ if (surf->w < g_system->getWidth() && surf->h < g_system->getHeight()) {
+ x = (g_system->getWidth() - surf->w) >> 1;
+ y = (g_system->getHeight() - surf->h) >> 1;
}
- g_system->copyRectToScreen(conv->getPixels(), conv->pitch, x, y, MIN<uint16>(conv->w, 640), MIN<uint16>(conv->h, 480));
+ g_system->copyRectToScreen(surf->getPixels(), surf->pitch, x, y, MIN<uint16>(surf->w, 640), MIN<uint16>(surf->h, 480));
- conv->free();
- delete conv;
+ if (conv) {
+ conv->free();
+ delete conv;
+ }
}
Common::Event event;
Commit: d72fee204cd787b63076b4479ed2b0b6bf56d6e9
https://github.com/scummvm/scummvm/commit/d72fee204cd787b63076b4479ed2b0b6bf56d6e9
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-04-05T12:45:13+02:00
Commit Message:
VIDEO: Implement setOutputPixelFormat() for MPEGPSDecoder
Changed paths:
engines/grim/movie/mpeg.cpp
video/mpegps_decoder.cpp
video/mpegps_decoder.h
diff --git a/engines/grim/movie/mpeg.cpp b/engines/grim/movie/mpeg.cpp
index 9a082282106..e6e3c05b806 100644
--- a/engines/grim/movie/mpeg.cpp
+++ b/engines/grim/movie/mpeg.cpp
@@ -45,8 +45,8 @@ bool MpegPlayer::loadFile(const Common::String &filename) {
if (!stream)
return false;
- _videoDecoder->setDefaultHighColorFormat(Graphics::PixelFormat(4, 8, 8, 8, 0, 8, 16, 24, 0));
_videoDecoder->loadStream(stream);
+ _videoDecoder->setOutputPixelFormat(Graphics::PixelFormat(4, 8, 8, 8, 0, 8, 16, 24, 0));
_videoDecoder->start();
return true;
diff --git a/video/mpegps_decoder.cpp b/video/mpegps_decoder.cpp
index b244594fe84..43219d6befb 100644
--- a/video/mpegps_decoder.cpp
+++ b/video/mpegps_decoder.cpp
@@ -205,7 +205,7 @@ bool MPEGPSDecoder::addFirstVideoTrack() {
// Video stream
// Can be MPEG-1/2 or MPEG-4/h.264. We'll assume the former and
// I hope we never need the latter.
- MPEGVideoTrack *track = new MPEGVideoTrack(packet, getDefaultHighColorFormat());
+ MPEGVideoTrack *track = new MPEGVideoTrack(packet);
addTrack(track);
_streamMap[startCode] = track;
@@ -584,14 +584,14 @@ void MPEGPSDecoder::MPEGPSDemuxer::parseProgramStreamMap(int length) {
// Video track
// --------------------------------------------------------------------------
-MPEGPSDecoder::MPEGVideoTrack::MPEGVideoTrack(Common::SeekableReadStream *firstPacket, const Graphics::PixelFormat &format) {
+MPEGPSDecoder::MPEGVideoTrack::MPEGVideoTrack(Common::SeekableReadStream *firstPacket) {
_surface = 0;
_endOfTrack = false;
_curFrame = -1;
_framePts = 0xFFFFFFFF;
_nextFrameStartTime = Audio::Timestamp(0, 27000000); // 27 MHz timer
- findDimensions(firstPacket, format);
+ findDimensions(firstPacket);
#ifdef USE_MPEG2
_mpegDecoder = new Image::MPEGDecoder();
@@ -610,18 +610,20 @@ MPEGPSDecoder::MPEGVideoTrack::~MPEGVideoTrack() {
}
uint16 MPEGPSDecoder::MPEGVideoTrack::getWidth() const {
- return _surface ? _surface->w : 0;
+ return _width;
}
uint16 MPEGPSDecoder::MPEGVideoTrack::getHeight() const {
- return _surface ? _surface->h : 0;
+ return _height;
}
Graphics::PixelFormat MPEGPSDecoder::MPEGVideoTrack::getPixelFormat() const {
- if (!_surface)
- return Graphics::PixelFormat();
+ return _pixelFormat;
+}
- return _surface->format;
+bool MPEGPSDecoder::MPEGVideoTrack::setOutputPixelFormat(const Graphics::PixelFormat &format) {
+ _pixelFormat = format;
+ return true;
}
const Graphics::Surface *MPEGPSDecoder::MPEGVideoTrack::decodeNextFrame() {
@@ -630,6 +632,11 @@ const Graphics::Surface *MPEGPSDecoder::MPEGVideoTrack::decodeNextFrame() {
bool MPEGPSDecoder::MPEGVideoTrack::sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts) {
#ifdef USE_MPEG2
+ if (!_surface) {
+ _surface = new Graphics::Surface();
+ _surface->create(_width, _height, _pixelFormat);
+ }
+
if (pts != 0xFFFFFFFF) {
_framePts = pts;
}
@@ -663,7 +670,7 @@ bool MPEGPSDecoder::MPEGVideoTrack::sendPacket(Common::SeekableReadStream *packe
#endif
}
-void MPEGPSDecoder::MPEGVideoTrack::findDimensions(Common::SeekableReadStream *firstPacket, const Graphics::PixelFormat &format) {
+void MPEGPSDecoder::MPEGVideoTrack::findDimensions(Common::SeekableReadStream *firstPacket) {
// First, check for the picture start code
if (firstPacket->readUint32BE() != 0x1B3)
error("Failed to detect MPEG sequence start");
@@ -671,15 +678,15 @@ void MPEGPSDecoder::MPEGVideoTrack::findDimensions(Common::SeekableReadStream *f
// This is part of the bitstream, but there's really no purpose
// to use Common::BitStream just for this: 12 bits width, 12 bits
// height
- uint16 width = firstPacket->readByte() << 4;
- uint16 height = firstPacket->readByte();
- width |= (height & 0xF0) >> 4;
- height = ((height & 0x0F) << 8) | firstPacket->readByte();
-
- debug(0, "MPEG dimensions: %dx%d", width, height);
-
- _surface = new Graphics::Surface();
- _surface->create(width, height, format);
+ _width = firstPacket->readByte() << 4;
+ _height = firstPacket->readByte();
+ _width |= (_height & 0xF0) >> 4;
+ _height = ((_height & 0x0F) << 8) | firstPacket->readByte();
+ _pixelFormat = g_system->getScreenFormat();
+ if (_pixelFormat.bytesPerPixel == 1)
+ _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0);
+
+ debug(0, "MPEG dimensions: %dx%d", _width, _height);
firstPacket->seek(0);
}
diff --git a/video/mpegps_decoder.h b/video/mpegps_decoder.h
index 3863a1e29b5..12c1a20529d 100644
--- a/video/mpegps_decoder.h
+++ b/video/mpegps_decoder.h
@@ -113,13 +113,14 @@ private:
// An MPEG 1/2 video track
class MPEGVideoTrack : public VideoTrack, public MPEGStream {
public:
- MPEGVideoTrack(Common::SeekableReadStream *firstPacket, const Graphics::PixelFormat &format);
+ MPEGVideoTrack(Common::SeekableReadStream *firstPacket);
~MPEGVideoTrack();
bool endOfTrack() const { return _endOfTrack; }
uint16 getWidth() const;
uint16 getHeight() const;
Graphics::PixelFormat getPixelFormat() const;
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format);
int getCurFrame() const { return _curFrame; }
uint32 getNextFrameStartTime() const { return _nextFrameStartTime.msecs(); }
const Graphics::Surface *decodeNextFrame();
@@ -136,7 +137,11 @@ private:
Audio::Timestamp _nextFrameStartTime;
Graphics::Surface *_surface;
- void findDimensions(Common::SeekableReadStream *firstPacket, const Graphics::PixelFormat &format);
+ uint16 _width;
+ uint16 _height;
+ Graphics::PixelFormat _pixelFormat;
+
+ void findDimensions(Common::SeekableReadStream *firstPacket);
#ifdef USE_MPEG2
Image::MPEGDecoder *_mpegDecoder;
Commit: adef12d993e9b92f4dbf97b12355063619173fcb
https://github.com/scummvm/scummvm/commit/adef12d993e9b92f4dbf97b12355063619173fcb
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-04-05T12:45:13+02:00
Commit Message:
VIDEO: Implement setOutputPixelFormat() for BinkDecoder
Changed paths:
engines/grim/movie/bink.cpp
engines/icb/movie_pc.cpp
engines/icb/options_manager_pc.cpp
engines/myst3/inventory.cpp
engines/myst3/menu.cpp
engines/myst3/movie.cpp
engines/myst3/puzzles.cpp
engines/myst3/subtitles.cpp
engines/scumm/he/animation_he.cpp
engines/stark/ui/world/fmvscreen.cpp
engines/stark/visual/smacker.cpp
video/bink_decoder.cpp
video/bink_decoder.h
diff --git a/engines/grim/movie/bink.cpp b/engines/grim/movie/bink.cpp
index 9e42b2b80e5..9279d8a1dec 100644
--- a/engines/grim/movie/bink.cpp
+++ b/engines/grim/movie/bink.cpp
@@ -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
diff --git a/engines/icb/movie_pc.cpp b/engines/icb/movie_pc.cpp
index 0dabe6e06d5..884de097fb0 100644
--- a/engines/icb/movie_pc.cpp
+++ b/engines/icb/movie_pc.cpp
@@ -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);
}
diff --git a/engines/icb/options_manager_pc.cpp b/engines/icb/options_manager_pc.cpp
index 218f37725d7..8dd845e6c76 100644
--- a/engines/icb/options_manager_pc.cpp
+++ b/engines/icb/options_manager_pc.cpp
@@ -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!");
diff --git a/engines/myst3/inventory.cpp b/engines/myst3/inventory.cpp
index 15933c6cea5..51e008bf0ef 100644
--- a/engines/myst3/inventory.cpp
+++ b/engines/myst3/inventory.cpp
@@ -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();
diff --git a/engines/myst3/menu.cpp b/engines/myst3/menu.cpp
index 958cc816b38..4817142ade7 100644
--- a/engines/myst3/menu.cpp
+++ b/engines/myst3/menu.cpp
@@ -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();
diff --git a/engines/myst3/movie.cpp b/engines/myst3/movie.cpp
index 78d6d8af6a3..5be07da80d8 100644
--- a/engines/myst3/movie.cpp
+++ b/engines/myst3/movie.cpp
@@ -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");
diff --git a/engines/myst3/puzzles.cpp b/engines/myst3/puzzles.cpp
index 05485522328..29e1ed18cfb 100644
--- a/engines/myst3/puzzles.cpp
+++ b/engines/myst3/puzzles.cpp
@@ -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();
diff --git a/engines/myst3/subtitles.cpp b/engines/myst3/subtitles.cpp
index ae41f93a109..75b210b81e8 100644
--- a/engines/myst3/subtitles.cpp
+++ b/engines/myst3/subtitles.cpp
@@ -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;
diff --git a/engines/scumm/he/animation_he.cpp b/engines/scumm/he/animation_he.cpp
index 59e9996fee9..a60796544cc 100644
--- a/engines/scumm/he/animation_he.cpp
+++ b/engines/scumm/he/animation_he.cpp
@@ -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());
diff --git a/engines/stark/ui/world/fmvscreen.cpp b/engines/stark/ui/world/fmvscreen.cpp
index fc1a97ea210..fa4bd7fbf8f 100644
--- a/engines/stark/ui/world/fmvscreen.cpp
+++ b/engines/stark/ui/world/fmvscreen.cpp
@@ -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();
}
diff --git a/engines/stark/visual/smacker.cpp b/engines/stark/visual/smacker.cpp
index 72db7c8f5a5..06ca3607421 100644
--- a/engines/stark/visual/smacker.cpp
+++ b/engines/stark/visual/smacker.cpp
@@ -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();
}
diff --git a/video/bink_decoder.cpp b/video/bink_decoder.cpp
index 30de3d478dc..0c371d6447c 100644
--- a/video/bink_decoder.cpp
+++ b/video/bink_decoder.cpp
@@ -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++) {
diff --git a/video/bink_decoder.h b/video/bink_decoder.h
index e21d6777a7f..e71c9d2fff1 100644
--- a/video/bink_decoder.h
+++ b/video/bink_decoder.h
@@ -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
Commit: 475354cb4c6dde54aff01dbe358d417db99d6617
https://github.com/scummvm/scummvm/commit/475354cb4c6dde54aff01dbe358d417db99d6617
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-04-05T12:45:13+02:00
Commit Message:
VIDEO: Implement setOutputPixelFormat() for PSXStreamDecoder
Changed paths:
video/psx_decoder.cpp
video/psx_decoder.h
diff --git a/video/psx_decoder.cpp b/video/psx_decoder.cpp
index 4658f0821d8..8a1b4355b1a 100644
--- a/video/psx_decoder.cpp
+++ b/video/psx_decoder.cpp
@@ -340,17 +340,21 @@ Audio::AudioStream *PSXStreamDecoder::PSXAudioTrack::getAudioStream() const {
}
-PSXStreamDecoder::PSXVideoTrack::PSXVideoTrack(Common::SeekableReadStream *firstSector, CDSpeed speed, int frameCount) : _nextFrameStartTime(0, speed), _frameCount(frameCount) {
+PSXStreamDecoder::PSXVideoTrack::PSXVideoTrack(Common::SeekableReadStream *firstSector, CDSpeed speed, int frameCount) : _nextFrameStartTime(0, speed), _frameCount(frameCount), _surface(nullptr) {
assert(firstSector);
firstSector->seek(40);
- uint16 width = firstSector->readUint16LE();
- uint16 height = firstSector->readUint16LE();
- _surface = new Graphics::Surface();
- _surface->create(width, height, g_system->getScreenFormat());
+ _width = firstSector->readUint16LE();
+ _height = firstSector->readUint16LE();
- _macroBlocksW = (width + 15) / 16;
- _macroBlocksH = (height + 15) / 16;
+ _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);
+
+ _macroBlocksW = (_width + 15) / 16;
+ _macroBlocksH = (_height + 15) / 16;
_yBuffer = new byte[_macroBlocksW * _macroBlocksH * 16 * 16];
_cbBuffer = new byte[_macroBlocksW * _macroBlocksH * 8 * 8];
_crBuffer = new byte[_macroBlocksW * _macroBlocksH * 8 * 8];
@@ -363,8 +367,10 @@ PSXStreamDecoder::PSXVideoTrack::PSXVideoTrack(Common::SeekableReadStream *first
}
PSXStreamDecoder::PSXVideoTrack::~PSXVideoTrack() {
- _surface->free();
- delete _surface;
+ if (_surface) {
+ _surface->free();
+ delete _surface;
+ }
delete[] _yBuffer;
delete[] _cbBuffer;
@@ -383,6 +389,11 @@ const Graphics::Surface *PSXStreamDecoder::PSXVideoTrack::decodeNextFrame() {
}
void PSXStreamDecoder::PSXVideoTrack::decodeFrame(Common::BitStreamMemoryStream *frame, uint sectorCount) {
+ if (!_surface) {
+ _surface = new Graphics::Surface();
+ _surface->create(_width, _height, _pixelFormat);
+ }
+
// A frame is essentially an MPEG-1 intra frame
Common::BitStreamMemory16LEMSB bits(frame);
diff --git a/video/psx_decoder.h b/video/psx_decoder.h
index a9af522e17b..f4914f3c913 100644
--- a/video/psx_decoder.h
+++ b/video/psx_decoder.h
@@ -80,9 +80,10 @@ private:
PSXVideoTrack(Common::SeekableReadStream *firstSector, CDSpeed speed, int frameCount);
~PSXVideoTrack();
- uint16 getWidth() const { return _surface->w; }
- uint16 getHeight() const { return _surface->h; }
- Graphics::PixelFormat getPixelFormat() const { return _surface->format; }
+ uint16 getWidth() const { return _width; }
+ uint16 getHeight() const { return _height; }
+ Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format) { _pixelFormat = format; return true; }
bool endOfTrack() const { return _endOfTrack; }
int getCurFrame() const { return _curFrame; }
int getFrameCount() const { return _frameCount; }
@@ -94,6 +95,9 @@ private:
private:
Graphics::Surface *_surface;
+ Graphics::PixelFormat _pixelFormat;
+ uint16 _width;
+ uint16 _height;
uint32 _frameCount;
Audio::Timestamp _nextFrameStartTime;
bool _endOfTrack;
Commit: 70a6159af5ae959bc134b55c23859e6747340bc0
https://github.com/scummvm/scummvm/commit/70a6159af5ae959bc134b55c23859e6747340bc0
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-04-05T12:45:13+02:00
Commit Message:
VIDEO: Implement setOutputPixelFormat() for TheoraDecoder
Changed paths:
video/theora_decoder.cpp
video/theora_decoder.h
diff --git a/video/theora_decoder.cpp b/video/theora_decoder.cpp
index b759ec4bf66..dca4b82a450 100644
--- a/video/theora_decoder.cpp
+++ b/video/theora_decoder.cpp
@@ -167,7 +167,7 @@ bool TheoraDecoder::loadStream(Common::SeekableReadStream *stream) {
// And now we have it all. Initialize decoders next
if (_hasVideo) {
- _videoTrack = new TheoraVideoTrack(getDefaultHighColorFormat(), theoraInfo, theoraSetup);
+ _videoTrack = new TheoraVideoTrack(theoraInfo, theoraSetup);
addTrack(_videoTrack);
}
@@ -254,7 +254,7 @@ Common::Rational TheoraDecoder::getFrameRate() const {
return Common::Rational();
}
-TheoraDecoder::TheoraVideoTrack::TheoraVideoTrack(const Graphics::PixelFormat &format, th_info &theoraInfo, th_setup_info *theoraSetup) {
+TheoraDecoder::TheoraVideoTrack::TheoraVideoTrack(th_info &theoraInfo, th_setup_info *theoraSetup) {
_theoraDecode = th_decode_alloc(&theoraInfo, theoraSetup);
if (theoraInfo.pixel_fmt != TH_PF_420)
@@ -264,11 +264,18 @@ TheoraDecoder::TheoraVideoTrack::TheoraVideoTrack(const Graphics::PixelFormat &f
th_decode_ctl(_theoraDecode, TH_DECCTL_GET_PPLEVEL_MAX, &postProcessingMax, sizeof(postProcessingMax));
th_decode_ctl(_theoraDecode, TH_DECCTL_SET_PPLEVEL, &postProcessingMax, sizeof(postProcessingMax));
- _surface.create(theoraInfo.frame_width, theoraInfo.frame_height, format);
+ _x = theoraInfo.pic_x;
+ _y = theoraInfo.pic_y;
+ _width = theoraInfo.pic_width;
+ _height = theoraInfo.pic_height;
+ _surfaceWidth = theoraInfo.frame_width;
+ _surfaceHeight = theoraInfo.frame_height;
- // Set up a display surface
- _displaySurface.init(theoraInfo.pic_width, theoraInfo.pic_height, _surface.pitch,
- _surface.getBasePtr(theoraInfo.pic_x, theoraInfo.pic_y), format);
+ _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);
// Set the frame rate
_frameRate = Common::Rational(theoraInfo.fps_numerator, theoraInfo.fps_denominator);
@@ -276,13 +283,24 @@ TheoraDecoder::TheoraVideoTrack::TheoraVideoTrack(const Graphics::PixelFormat &f
_endOfVideo = false;
_nextFrameStartTime = 0.0;
_curFrame = -1;
+ _surface = nullptr;
+ _displaySurface = nullptr;
}
TheoraDecoder::TheoraVideoTrack::~TheoraVideoTrack() {
th_decode_free(_theoraDecode);
- _surface.free();
- _displaySurface.setPixels(0);
+ if (_surface) {
+ _surface->free();
+ delete _surface;
+ _surface = nullptr;
+ }
+
+ if (_displaySurface) {
+ _displaySurface->setPixels(0);
+ delete _displaySurface;
+ _displaySurface = nullptr;
+ }
}
bool TheoraDecoder::TheoraVideoTrack::decodePacket(ogg_packet &oggPacket) {
@@ -330,7 +348,19 @@ void TheoraDecoder::TheoraVideoTrack::translateYUVtoRGBA(th_ycbcr_buffer &YUVBuf
assert(YUVBuffer[kBufferU].height == YUVBuffer[kBufferY].height >> 1);
assert(YUVBuffer[kBufferV].height == YUVBuffer[kBufferY].height >> 1);
- YUVToRGBMan.convert420(&_surface, Graphics::YUVToRGBManager::kScaleITU, YUVBuffer[kBufferY].data, YUVBuffer[kBufferU].data, YUVBuffer[kBufferV].data, YUVBuffer[kBufferY].width, YUVBuffer[kBufferY].height, YUVBuffer[kBufferY].stride, YUVBuffer[kBufferU].stride);
+ if (!_surface) {
+ _surface = new Graphics::Surface();
+ _surface->create(_surfaceWidth, _surfaceHeight, _pixelFormat);
+ }
+
+ // Set up a display surface
+ if (!_displaySurface) {
+ _displaySurface = new Graphics::Surface();
+ _displaySurface->init(_width, _height, _surface->pitch,
+ _surface->getBasePtr(_x, _y), _surface->format);
+ }
+
+ YUVToRGBMan.convert420(_surface, Graphics::YUVToRGBManager::kScaleITU, YUVBuffer[kBufferY].data, YUVBuffer[kBufferU].data, YUVBuffer[kBufferV].data, YUVBuffer[kBufferY].width, YUVBuffer[kBufferY].height, YUVBuffer[kBufferY].stride, YUVBuffer[kBufferU].stride);
}
static vorbis_info *info = 0;
diff --git a/video/theora_decoder.h b/video/theora_decoder.h
index 8979c8670b7..6adf2123cec 100644
--- a/video/theora_decoder.h
+++ b/video/theora_decoder.h
@@ -79,17 +79,18 @@ protected:
private:
class TheoraVideoTrack : public VideoTrack {
public:
- TheoraVideoTrack(const Graphics::PixelFormat &format, th_info &theoraInfo, th_setup_info *theoraSetup);
+ TheoraVideoTrack(th_info &theoraInfo, th_setup_info *theoraSetup);
~TheoraVideoTrack();
bool endOfTrack() const { return _endOfVideo; }
- uint16 getWidth() const { return _displaySurface.w; }
- uint16 getHeight() const { return _displaySurface.h; }
- Graphics::PixelFormat getPixelFormat() const { return _displaySurface.format; }
+ uint16 getWidth() const { return _width; }
+ uint16 getHeight() const { return _height; }
+ Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format) { _pixelFormat = format; return true; }
int getCurFrame() const { return _curFrame; }
const Common::Rational &getFrameRate() const { return _frameRate; }
uint32 getNextFrameStartTime() const { return (uint32)(_nextFrameStartTime * 1000); }
- const Graphics::Surface *decodeNextFrame() { return &_displaySurface; }
+ const Graphics::Surface *decodeNextFrame() { return _displaySurface; }
bool decodePacket(ogg_packet &oggPacket);
void setEndOfVideo() { _endOfVideo = true; }
@@ -100,8 +101,15 @@ private:
Common::Rational _frameRate;
double _nextFrameStartTime;
- Graphics::Surface _surface;
- Graphics::Surface _displaySurface;
+ Graphics::Surface *_surface;
+ Graphics::Surface *_displaySurface;
+ Graphics::PixelFormat _pixelFormat;
+ int _x;
+ int _y;
+ uint16 _width;
+ uint16 _height;
+ uint16 _surfaceWidth;
+ uint16 _surfaceHeight;
th_dec_ctx *_theoraDecode;
Commit: e6260bf0890bfb79133022c982a801f9eb8a0463
https://github.com/scummvm/scummvm/commit/e6260bf0890bfb79133022c982a801f9eb8a0463
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-04-05T12:45:13+02:00
Commit Message:
VIDEO: Implement setOutputPixelFormat() for MKVDecoder
Changed paths:
video/mkv_decoder.cpp
video/mkv_decoder.h
diff --git a/video/mkv_decoder.cpp b/video/mkv_decoder.cpp
index b6cd9ae15db..9e0efa5e421 100644
--- a/video/mkv_decoder.cpp
+++ b/video/mkv_decoder.cpp
@@ -171,7 +171,7 @@ bool MKVDecoder::loadStream(Common::SeekableReadStream *stream) {
if (trackType == mkvparser::Track::kVideo && _vTrack < 0) {
_vTrack = pTrack->GetNumber();
- _videoTrack = new VPXVideoTrack(getDefaultHighColorFormat(), pTrack);
+ _videoTrack = new VPXVideoTrack(pTrack);
addTrack(_videoTrack);
}
@@ -310,15 +310,18 @@ void MKVDecoder::readNextPacket() {
}
}
-MKVDecoder::VPXVideoTrack::VPXVideoTrack(const Graphics::PixelFormat &format, const mkvparser::Track *const pTrack) {
+MKVDecoder::VPXVideoTrack::VPXVideoTrack(const mkvparser::Track *const pTrack) {
const mkvparser::VideoTrack *const pVideoTrack = static_cast<const mkvparser::VideoTrack *>(pTrack);
- const long long width = pVideoTrack->GetWidth();
- const long long height = pVideoTrack->GetHeight();
+ _width = pVideoTrack->GetWidth();
+ _height = pVideoTrack->GetHeight();
+ _pixelFormat = g_system->getScreenFormat();
- debug(1, "VideoTrack: %lld x %lld", width, height);
+ // 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);
- _displaySurface.create(width, height, format);
+ debug(1, "VideoTrack: %d x %d", _width, _height);
_endOfVideo = false;
_nextFrameStartTime = 0.0;
@@ -332,7 +335,6 @@ MKVDecoder::VPXVideoTrack::VPXVideoTrack(const Graphics::PixelFormat &format, co
}
MKVDecoder::VPXVideoTrack::~VPXVideoTrack() {
- _displaySurface.free();
// The last frame is not freed in decodeNextFrame(), clear it hear instead.
_surface.free();
delete _codec;
diff --git a/video/mkv_decoder.h b/video/mkv_decoder.h
index 606129879c5..e651041baf4 100644
--- a/video/mkv_decoder.h
+++ b/video/mkv_decoder.h
@@ -88,13 +88,14 @@ protected:
private:
class VPXVideoTrack : public VideoTrack {
public:
- VPXVideoTrack(const Graphics::PixelFormat &format, const mkvparser::Track *const pTrack);
+ VPXVideoTrack(const mkvparser::Track *const pTrack);
~VPXVideoTrack();
bool endOfTrack() const;
- uint16 getWidth() const { return _displaySurface.w; }
- uint16 getHeight() const { return _displaySurface.h; }
- Graphics::PixelFormat getPixelFormat() const { return _displaySurface.format; }
+ uint16 getWidth() const { return _width; }
+ uint16 getHeight() const { return _height; }
+ Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
+ bool setOutputPixelFormat(const Graphics::PixelFormat &format) { _pixelFormat = format; return true; }
int getCurFrame() const { return _curFrame; }
uint32 getNextFrameStartTime() const { return (uint32)(_nextFrameStartTime * 1000); }
const Graphics::Surface *decodeNextFrame();
@@ -106,8 +107,11 @@ private:
bool _endOfVideo;
double _nextFrameStartTime;
+ uint16 _width;
+ uint16 _height;
+ Graphics::PixelFormat _pixelFormat;
+
Graphics::Surface _surface;
- Graphics::Surface _displaySurface;
Common::Queue<Graphics::Surface> _displayQueue;
vpx_codec_ctx_t *_codec = nullptr;
Commit: 75e8dd71b77739ee6cbdaa474a66908e33dc3e23
https://github.com/scummvm/scummvm/commit/75e8dd71b77739ee6cbdaa474a66908e33dc3e23
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-04-05T12:45:13+02:00
Commit Message:
ASYLUM: Select the best pixel format for video playback
Changed paths:
engines/asylum/views/video.cpp
diff --git a/engines/asylum/views/video.cpp b/engines/asylum/views/video.cpp
index 6a4785a297a..1fc55147b3a 100644
--- a/engines/asylum/views/video.cpp
+++ b/engines/asylum/views/video.cpp
@@ -189,14 +189,16 @@ void VideoPlayer::play(const Common::String &filename, bool showSubtitles) {
int32 frameEnd = 0;
int32 currentSubtitle = 0;
- _decoder->start();
-
if (_vm->checkGameVersion("Steam") || _vm->isAltDemo()) {
- Graphics::PixelFormat decoderFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
- _decoder->setDefaultHighColorFormat(decoderFormat);
+ Graphics::PixelFormat bestFormat = g_system->getSupportedFormats().front();
+ _decoder->setOutputPixelFormat(bestFormat);
+
+ Graphics::PixelFormat decoderFormat = _decoder->getPixelFormat();
initGraphics(640, 480, &decoderFormat);
}
+ _decoder->start();
+
while (!_done && !Engine::shouldQuit() && !_decoder->endOfVideo()) {
_vm->handleEvents();
Commit: 5956fa4757fe303fdaeb386f637ec27590a5a5fc
https://github.com/scummvm/scummvm/commit/5956fa4757fe303fdaeb386f637ec27590a5a5fc
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-04-05T12:45:13+02:00
Commit Message:
VIDEO: Remove VideoDecoder::setDefaultHighColorFormat()
Changed paths:
video/video_decoder.cpp
video/video_decoder.h
diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp
index 094359df7a9..b1209b52848 100644
--- a/video/video_decoder.cpp
+++ b/video/video_decoder.cpp
@@ -49,12 +49,6 @@ VideoDecoder::VideoDecoder() {
_mainAudioTrack = 0;
_canSetDither = true;
_canSetDefaultFormat = true;
-
- // Find the best format for output
- _defaultHighColorFormat = g_system->getScreenFormat();
-
- if (_defaultHighColorFormat.bytesPerPixel == 1)
- _defaultHighColorFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0);
}
void VideoDecoder::close() {
diff --git a/video/video_decoder.h b/video/video_decoder.h
index 6d41dbaafd5..215a3eef6b0 100644
--- a/video/video_decoder.h
+++ b/video/video_decoder.h
@@ -356,16 +356,6 @@ public:
*/
virtual const Graphics::Surface *decodeNextFrame();
- /**
- * Set the default high color format for videos that convert from YUV.
- *
- * By default, VideoDecoder will attempt to use the screen format
- * if it's >8bpp and use a 32bpp format when not.
- *
- * This must be set before calling loadStream().
- */
- void setDefaultHighColorFormat(const Graphics::PixelFormat &format) { _defaultHighColorFormat = format; }
-
/**
* Set the video to decode frames in reverse.
*
@@ -382,7 +372,7 @@ public:
* Tell the video to dither to a palette.
*
* By default, VideoDecoder will return surfaces in native, or in the case
- * of YUV-based videos, the format set by setDefaultHighColorFormat().
+ * of YUV-based videos, the format set by setOutputPixelFormat().
* For video formats or codecs that support it, this will start outputting
* its surfaces in 8bpp with this palette.
*
@@ -892,11 +882,6 @@ protected:
*/
bool endOfVideoTracks() const;
- /**
- * Get the default high color format
- */
- Graphics::PixelFormat getDefaultHighColorFormat() const { return _defaultHighColorFormat; }
-
/**
* Set _nextVideoTrack to the video track with the lowest start time for the next frame.
*
@@ -974,9 +959,6 @@ private:
bool _canSetDither;
bool _canSetDefaultFormat;
- // Default PixelFormat settings
- Graphics::PixelFormat _defaultHighColorFormat;
-
protected:
// Internal helper functions
void stopAudio();
More information about the Scummvm-git-logs
mailing list