[Scummvm-git-logs] scummvm master -> 54240bdac64b5d19c08852180d127faa0789ba0e

rvanlaar noreply at scummvm.org
Sat Mar 5 21:14:27 UTC 2022


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
bee055140f DIRECTOR: Sanity check PACo palette was off by one
e931a1a985 VIDEO: PACo decoder: refactor for audio track
54240bdac6 VIDEO: PACo decoder: Add audio support


Commit: bee055140fbfd139df1c2f75f569d98e343037d8
    https://github.com/scummvm/scummvm/commit/bee055140fbfd139df1c2f75f569d98e343037d8
Author: Roland van Laar (roland at rolandvanlaar.nl)
Date: 2022-03-05T22:11:40+01:00

Commit Message:
DIRECTOR: Sanity check PACo palette was off by one

Palette has a length of 256.

Changed paths:
    engines/director/lingo/lingo-builtins.cpp


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 18134c9b333..c9c8388d2ab 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -2711,9 +2711,9 @@ void LB::b_xPlayAnim(int nargs){
 	byte origPalette[256 * 3];
 	uint16 origCount = g_director->getPaletteColorCount();
 
-	if (origCount > 255) {
+	if (origCount > 256) {
 		warning("b_xPlayAnim: too big palette, %d > 256", origCount);
-		origCount = 255;
+		origCount = 256;
 	}
 
 	memcpy(origPalette, g_director->getPalette(), origCount * 3);


Commit: e931a1a9854dfba40c4813ed6b99efb2256c7ad6
    https://github.com/scummvm/scummvm/commit/e931a1a9854dfba40c4813ed6b99efb2256c7ad6
Author: Roland van Laar (roland at rolandvanlaar.nl)
Date: 2022-03-05T22:11:40+01:00

Commit Message:
VIDEO: PACo decoder: refactor for audio track

A PACo 'frame' has both the audio and video part of the frame. Where decodeNextFrame only handles video, readNextPacket enables the option to read a PACo frame and decode and queue both audio and video.

Changed paths:
    video/paco_decoder.cpp
    video/paco_decoder.h


diff --git a/video/paco_decoder.cpp b/video/paco_decoder.cpp
index 457cf2f7c5d..9ffbcb1f53a 100644
--- a/video/paco_decoder.cpp
+++ b/video/paco_decoder.cpp
@@ -44,6 +44,7 @@ PacoDecoder::~PacoDecoder() {
 bool PacoDecoder::loadStream(Common::SeekableReadStream *stream) {
 	close();
 
+	_curFrame = 0;
 	stream->readUint16BE(); // 1
 	stream->readUint16BE(); // 0x26
 
@@ -64,7 +65,15 @@ bool PacoDecoder::loadStream(Common::SeekableReadStream *stream) {
 	stream->readUint32BE(); // flags
 	stream->readUint16BE(); // 0
 
-	addTrack(new PacoVideoTrack(stream, frameRate, frameCount, hasAudio, width, height));
+	for (uint i = 0; i < frameCount; i++) {
+		_frameSizes[i] = stream->readUint32BE();
+	}
+
+	_fileStream = stream;
+
+	_videoTrack = new PacoVideoTrack(frameRate, frameCount, width, height);
+	addTrack(_videoTrack);
+
 	return true;
 }
 
@@ -105,9 +114,8 @@ const byte* PacoDecoder::PacoVideoTrack::getPalette() const {
 }
 
 PacoDecoder::PacoVideoTrack::PacoVideoTrack(
-	Common::SeekableReadStream *stream, uint16 frameRate, uint16 frameCount, bool hasAudio, uint16 width, uint16 height) {
-
-	_fileStream = stream;
+	uint16 frameRate, uint16 frameCount, uint16 width, uint16 height) {
+	_curFrame = 0;
 	_frameRate = frameRate;
 	_frameCount = frameCount;
 
@@ -115,16 +123,9 @@ PacoDecoder::PacoVideoTrack::PacoVideoTrack(
 	_surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
 	_palette = const_cast<byte *>(quickTimeDefaultPalette256);
 	_dirtyPalette = true;
-
-	_curFrame = 0;
-
-	for (uint i = 0; i < _frameCount; i++) {
-		_frameSizes[i] = stream->readUint32BE();
-	}
 }
 
 PacoDecoder::PacoVideoTrack::~PacoVideoTrack() {
-	delete _fileStream;
 	_surface->free();
 	delete _surface;
 }
@@ -161,11 +162,13 @@ enum frameTypes {
 	EOC = 11 // - end of chunk marker
 };
 
-const Graphics::Surface *PacoDecoder::PacoVideoTrack::decodeNextFrame() {
+void PacoDecoder::readNextPacket() {
 	uint32 nextFrame = _fileStream->pos() + _frameSizes[_curFrame];
 
 	debug(2, " frame %3d size %d @ %lX", _curFrame, _frameSizes[_curFrame], _fileStream->pos());
 
+	_curFrame++;
+
 	while (_fileStream->pos() < nextFrame) {
 		int64 currentPos = _fileStream->pos();
 		int frameType = _fileStream->readByte();
@@ -178,10 +181,10 @@ const Graphics::Surface *PacoDecoder::PacoVideoTrack::decodeNextFrame() {
 			warning("PacoDecode::decodeFrame(): Audio not implemented");
 			break;
 		case VIDEO:
-			handleFrame(chunkSize - 4);
+			_videoTrack->handleFrame(_fileStream, chunkSize - 4, _curFrame);
 			break;
 		case PALLETE:
-			handlePalette();
+			_videoTrack->handlePalette(_fileStream);
 			break;
 		case EOC:
 			break;
@@ -192,20 +195,22 @@ const Graphics::Surface *PacoDecoder::PacoVideoTrack::decodeNextFrame() {
 		_fileStream->seek(currentPos + chunkSize);
 	 }
 
-	_curFrame++;
 
+}
+
+const Graphics::Surface *PacoDecoder::PacoVideoTrack::decodeNextFrame() {
 	return _surface;
 }
 
-void PacoDecoder::PacoVideoTrack::handlePalette() {
-	uint32 header = _fileStream->readUint32BE();
+void PacoDecoder::PacoVideoTrack::handlePalette(Common::SeekableReadStream *fileStream) {
+	uint32 header = fileStream->readUint32BE();
 	if (header == 0x30000000) { // default quicktime palette
 		_palette = const_cast<byte *>(quickTimeDefaultPalette256);
 	} else {
-		_fileStream->readUint32BE(); // 4 bytes of 00
+		fileStream->readUint32BE(); // 4 bytes of 00
 		_palette = new byte[256 * 3]();
 		for (int i = 0; i < 256 * 3; i++){
-			_palette[i] = _fileStream->readByte();
+			_palette[i] = fileStream->readByte();
 		}
 	}
 	_dirtyPalette = true;
@@ -246,23 +251,24 @@ enum {
 	} while(0);
 
 
-void PacoDecoder::PacoVideoTrack::handleFrame(uint32 chunkSize) {
+void PacoDecoder::PacoVideoTrack::handleFrame(Common::SeekableReadStream *fileStream, uint32 chunkSize, int curFrame) {
+	_curFrame = curFrame;
 	uint16 w = getWidth();
 
-	uint16 x = _fileStream->readUint16BE();			// x offset of the updated area
-	uint16 y = _fileStream->readUint16BE();			// y offset of the updated area
-	uint16 bw = _fileStream->readUint16BE();		// updated area width
-	uint16 bh = _fileStream->readUint16BE();		// updated area height
-	uint compr = _fileStream->readByte();	    	// compression method and flags
-	_fileStream->readByte();						// padding
+	uint16 x = fileStream->readUint16BE();			// x offset of the updated area
+	uint16 y = fileStream->readUint16BE();			// y offset of the updated area
+	uint16 bw = fileStream->readUint16BE();			// updated area width
+	uint16 bh = fileStream->readUint16BE();			// updated area height
+	uint compr = fileStream->readByte();	    	// compression method and flags
+	fileStream->readByte();							// padding
 
 	debug(5, "    +%d,%d - %dx%d compr %X", x, y, bw, bh, compr);
 
 	compr = compr & 0xF;
 
 	uint8 *fdata = new uint8[1048576];              // 0x100000 copied from original pacodec
-	_fileStream->read(fdata, chunkSize - 10);       // remove header length
-	debug(5, "pos: %ld", _fileStream->pos());
+	fileStream->read(fdata, chunkSize - 10);       // remove header length
+	debug(5, "pos: %ld", fileStream->pos());
 	int16 xpos = x, ypos = y, ypos2 = y;
 	byte *dst = (byte *)_surface->getPixels() + x + y * w;
 
diff --git a/video/paco_decoder.h b/video/paco_decoder.h
index feca06f946d..387da2cc409 100644
--- a/video/paco_decoder.h
+++ b/video/paco_decoder.h
@@ -22,9 +22,9 @@
 #ifndef VIDEO_PACODECODER_H
 #define VIDEO_PACODECODER_H
 
-#include "video/video_decoder.h"
 #include "common/list.h"
 #include "common/rect.h"
+#include "video/video_decoder.h"
 
 namespace Common {
 class SeekableReadStream;
@@ -33,7 +33,7 @@ class SeekableReadStream;
 namespace Graphics {
 struct PixelFormat;
 struct Surface;
-}
+} // namespace Graphics
 
 namespace Video {
 
@@ -54,14 +54,14 @@ public:
 	void clearDirtyRects();
 	void copyDirtyRectsToBuffer(uint8 *dst, uint pitch);
 	const byte *getPalette();
+	virtual void readNextPacket() override;
 
-protected:
 
+protected:
 	class PacoVideoTrack : public FixedRateVideoTrack {
 	public:
 		PacoVideoTrack(
-			Common::SeekableReadStream *stream, uint16 frameRate, uint16 frameCount,
-			bool hasAudio, uint16 width, uint16 height);
+			uint16 frameRate, uint16 frameCount,  uint16 width, uint16 height);
 		~PacoVideoTrack();
 
 		bool endOfTrack() const override;
@@ -73,8 +73,8 @@ protected:
 		int getCurFrame() const override { return _curFrame; }
 		int getFrameCount() const override { return _frameCount; }
 		virtual const Graphics::Surface *decodeNextFrame() override;
-		virtual void handleFrame(uint32 chunkSize);
-		void handlePalette();
+		virtual void handleFrame(Common::SeekableReadStream *fileStream, uint32 chunkSize, int curFrame);
+		void handlePalette(Common::SeekableReadStream *fileStream);
 		const byte *getPalette() const override;
 		bool hasDirtyPalette() const override { return _dirtyPalette; }
 
@@ -83,24 +83,27 @@ protected:
 		void copyDirtyRectsToBuffer(uint8 *dst, uint pitch);
 		Common::Rational getFrameRate() const override { return Common::Rational(_frameRate, 1); }
 
-
 	protected:
-		Common::SeekableReadStream *_fileStream;
 		Graphics::Surface *_surface;
 
-		int _curFrame;
-
 		byte *_palette;
 
-		int _frameSizes[65536]; // can be done differently?
 		mutable bool _dirtyPalette;
 
+		int _curFrame;
 		uint32 _frameCount;
 		uint32 _frameDelay;
 		uint16 _frameRate;
 
 		Common::List<Common::Rect> _dirtyRects;
 	};
+
+private:
+	PacoVideoTrack *_videoTrack;
+	Common::SeekableReadStream *_fileStream;
+	int _curFrame = 0;
+	int _frameSizes[65536]; // can be done differently?
+
 };
 
 } // End of namespace Video


Commit: 54240bdac64b5d19c08852180d127faa0789ba0e
    https://github.com/scummvm/scummvm/commit/54240bdac64b5d19c08852180d127faa0789ba0e
Author: Roland van Laar (roland at rolandvanlaar.nl)
Date: 2022-03-05T22:11:40+01:00

Commit Message:
VIDEO: PACo decoder: Add audio support

PACo audio is single channel 8 bit unsigned pcm.
The first sound packet is read to determine the sampling rate.

Changed paths:
    video/paco_decoder.cpp
    video/paco_decoder.h


diff --git a/video/paco_decoder.cpp b/video/paco_decoder.cpp
index 9ffbcb1f53a..99e5b5a275c 100644
--- a/video/paco_decoder.cpp
+++ b/video/paco_decoder.cpp
@@ -34,6 +34,21 @@
 
 namespace Video {
 
+enum frameTypes {
+	NOP = 0, // nop
+	// 1 - old initialisation data?
+	PALLETE = 2, // - new initialisation data (usually 0x30 0x00 0x00 ... meaning 8-bit with default QuickTime palette)
+	DELAY = 3, //  - delay information
+	AUDIO = 4, // - audio data (8-bit unsigned PCM)
+	// 5 - should not be present
+	// 6 - should not be present
+	// 7 - unknown
+	VIDEO = 8, // - video frame
+	// 9 - unknown
+	// 10 - dummy?
+	EOC = 11 // - end of chunk marker
+};
+
 PacoDecoder::PacoDecoder() {
 }
 
@@ -73,10 +88,42 @@ bool PacoDecoder::loadStream(Common::SeekableReadStream *stream) {
 
 	_videoTrack = new PacoVideoTrack(frameRate, frameCount, width, height);
 	addTrack(_videoTrack);
-
+	if (hasAudio) {
+		_audioTrack = new PacoAudioTrack(getAudioSamplingRate());
+		addTrack(_audioTrack);
+	}
 	return true;
 }
 
+int PacoDecoder::getAudioSamplingRate() {
+	/**
+	 * SamplingRate is found inside the audio packets
+	 * Search for the first audio packet and use it.
+	 */
+	const Common::Array<int> samplingRates = {5563, 7418, 11127, 22254};
+	int index;
+
+	int64 startPos = _fileStream->pos();
+
+	while (true){
+		int64 currentPos = _fileStream->pos();
+		int frameType = _fileStream->readByte();
+		int v = _fileStream->readByte();
+		uint32 chunkSize =  (v << 16 ) | _fileStream->readUint16BE();
+		if (frameType != AUDIO) {
+			_fileStream->seek(currentPos + chunkSize);
+			continue;
+		}
+		uint16 header = _fileStream->readUint16BE();
+		_fileStream->readUint16BE();
+		index = (header >> 10) & 7;
+		break;
+	}
+	_fileStream->seek(startPos);
+
+	return samplingRates[index];
+}
+
 const Common::List<Common::Rect> *PacoDecoder::getDirtyRects() const {
 	const Track *track = getTrack(0);
 
@@ -146,22 +193,6 @@ Graphics::PixelFormat PacoDecoder::PacoVideoTrack::getPixelFormat() const {
 	return _surface->format;
 }
 
-
-enum frameTypes {
-	NOP = 0, // nop
-	// 1 - old initialisation data?
-	PALLETE = 2, // - new initialisation data (usually 0x30 0x00 0x00 ... meaning 8-bit with default QuickTime palette)
-	DELAY = 3, //  - delay information
-	AUDIO = 4, // - audio data (8-bit unsigned PCM)
-	// 5 - should not be present
-	// 6 - should not be present
-	// 7 - unknown
-	VIDEO = 8, // - video frame
-	// 9 - unknown
-	// 10 - dummy?
-	EOC = 11 // - end of chunk marker
-};
-
 void PacoDecoder::readNextPacket() {
 	uint32 nextFrame = _fileStream->pos() + _frameSizes[_curFrame];
 
@@ -178,7 +209,7 @@ void PacoDecoder::readNextPacket() {
 
 		switch (frameType) {
 		case AUDIO:
-			warning("PacoDecode::decodeFrame(): Audio not implemented");
+			_audioTrack->queueSound(_fileStream, chunkSize - 4);
 			break;
 		case VIDEO:
 			_videoTrack->handleFrame(_fileStream, chunkSize - 4, _curFrame);
@@ -529,4 +560,24 @@ void PacoDecoder::PacoVideoTrack::copyDirtyRectsToBuffer(uint8 *dst, uint pitch)
 	clearDirtyRects();
 }
 
+PacoDecoder::PacoAudioTrack::PacoAudioTrack(int samplingRate)
+	: AudioTrack(Audio::Mixer::kPlainSoundType) {
+	_samplingRate = samplingRate;
+	byte audioFlags = Audio::FLAG_UNSIGNED;
+	_packetStream = Audio::makePacketizedRawStream(samplingRate, audioFlags);
+}
+
+void PacoDecoder::PacoAudioTrack::queueSound(Common::SeekableReadStream *fileStream, uint32 chunkSize) {
+	const Common::Array<int> samplingRates = {5563, 7418, 11127, 22254};
+	uint16 header = fileStream->readUint16BE();
+	fileStream->readUint16BE();
+	int index = (header >> 10) & 7;
+	int currentRate = samplingRates[index];
+	if ( currentRate != _samplingRate)
+		warning("PacoDecoder::PacoAudioTrack: Sampling rate differs from first frame: %i != %i", currentRate, _samplingRate);
+
+	_packetStream->queuePacket(fileStream->readStream(chunkSize - 4));
+}
+
+
 } // End of namespace Video
diff --git a/video/paco_decoder.h b/video/paco_decoder.h
index 387da2cc409..1ee803c9d52 100644
--- a/video/paco_decoder.h
+++ b/video/paco_decoder.h
@@ -22,6 +22,7 @@
 #ifndef VIDEO_PACODECODER_H
 #define VIDEO_PACODECODER_H
 
+#include "audio/audiostream.h"
 #include "common/list.h"
 #include "common/rect.h"
 #include "video/video_decoder.h"
@@ -98,12 +99,26 @@ protected:
 		Common::List<Common::Rect> _dirtyRects;
 	};
 
+	class PacoAudioTrack : public AudioTrack {
+	public:
+		PacoAudioTrack(int samplingRate);
+		void queueSound(Common::SeekableReadStream *fileStream, uint32 chunkSize);
+
+	protected:
+		Audio::AudioStream *getAudioStream() const { return _packetStream; }
+
+	private:
+		Audio::PacketizedAudioStream *_packetStream;
+		int _samplingRate;
+	};
+
 private:
 	PacoVideoTrack *_videoTrack;
+	PacoAudioTrack *_audioTrack;
 	Common::SeekableReadStream *_fileStream;
 	int _curFrame = 0;
 	int _frameSizes[65536]; // can be done differently?
-
+	int getAudioSamplingRate();
 };
 
 } // End of namespace Video




More information about the Scummvm-git-logs mailing list