diff options
| author | Torbjörn Andersson | 2015-08-04 19:14:03 +0200 | 
|---|---|---|
| committer | Thierry Crozat | 2018-11-04 22:33:22 +0100 | 
| commit | ad41dfb7ff25daf9e974c6c9dbdfb099307af4f7 (patch) | |
| tree | b4140153134a84d73ec7dd8af9827cbc09756e4f | |
| parent | e9052a008578b42ca5f5e869ef9e6ebe969cb929 (diff) | |
| download | scummvm-rg350-ad41dfb7ff25daf9e974c6c9dbdfb099307af4f7.tar.gz scummvm-rg350-ad41dfb7ff25daf9e974c6c9dbdfb099307af4f7.tar.bz2 scummvm-rg350-ad41dfb7ff25daf9e974c6c9dbdfb099307af4f7.zip | |
VIDEO: Committed fixes from clone2727
This collects the whole frame before trying to decode it. It's
still now working right, but it's way better than it was before.
| -rw-r--r-- | video/mpegps_decoder.cpp | 104 | ||||
| -rw-r--r-- | video/mpegps_decoder.h | 5 | 
2 files changed, 76 insertions, 33 deletions
| diff --git a/video/mpegps_decoder.cpp b/video/mpegps_decoder.cpp index af9e4f5bb0..e34053da73 100644 --- a/video/mpegps_decoder.cpp +++ b/video/mpegps_decoder.cpp @@ -553,11 +553,14 @@ MPEGPSDecoder::AC3AudioTrack::AC3AudioTrack(Common::SeekableReadStream *firstPac  	initStream(firstPacket);  	if (_sampleRate >= 0) {  		_audStream = Audio::makeQueuingAudioStream(_sampleRate, true); -		decodeAC3Data(firstPacket);  	} else {  		_audStream = 0;  		firstPacket->seek(0);  	} + +	_inBufPtr = _inBuf; +	_flags = 0; +	_frameSize = 0;  }  MPEGPSDecoder::AC3AudioTrack::~AC3AudioTrack() { @@ -567,7 +570,6 @@ MPEGPSDecoder::AC3AudioTrack::~AC3AudioTrack() {  bool MPEGPSDecoder::AC3AudioTrack::sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts) {  	if (_audStream) { -		initStream(packet);  		decodeAC3Data(packet);  	}  	delete packet; @@ -591,47 +593,85 @@ void MPEGPSDecoder::AC3AudioTrack::initStream(Common::SeekableReadStream *packet  		packet->seek(i, SEEK_SET);  		packet->read(buf, sizeof(buf)); -		_packetLength = a52_syncinfo(buf, &flags, &_sampleRate, &bitRate); +		int packetLength = a52_syncinfo(buf, &flags, &_sampleRate, &bitRate); -		if (_packetLength > 0) { +		if (packetLength > 0) {  			break;  		}  	}  } +enum { +	HEADER_SIZE = 7 +}; +  void MPEGPSDecoder::AC3AudioTrack::decodeAC3Data(Common::SeekableReadStream *packet) { -	// This doesn't work since _packetLength is often longer than the, -	// stream, which may go a long way towards explaining all the Valgrind -	// errors I'm getting. Not to mention that the output sounds nothing -	// at all like what I want. -	byte *buf = new byte[_packetLength]; -	packet->read(buf, _packetLength); - -	int flags = A52_STEREO | A52_ADJUST_LEVEL; -	sample_t level = 32767; -	int bias = 0; - -	if (a52_frame(_a52State, buf, &flags, &level, bias) == 0) { -		int16 *outputBuffer = (int16 *)malloc(6 * 512 * sizeof(int16)); -		int16 *outputPtr = outputBuffer; -		int outputLength = 0; -		for (int i = 0; i < 6; i++) { -			if (a52_block(_a52State)) { -				sample_t *samples = a52_samples(_a52State); -				for (int j = 0; j < 256; j++) { -					outputPtr[j * 2] = (int16)samples[j]; -					outputPtr[j * 2 + 1] = (int16)samples[256 + j]; +	while (packet->pos() < packet->size()) { +		uint32 leftSize = packet->size() - packet->pos(); +		uint32 len = _inBufPtr - _inBuf; +		if (_frameSize == 0) { +			// No header seen: find one +			len = HEADER_SIZE - len; +			if (len > leftSize) +				len = leftSize; +			packet->read(_inBufPtr, len); +			leftSize -= len; +			_inBufPtr += len; +			if ((_inBufPtr - _inBuf) == HEADER_SIZE) { +				int sampleRate, bitRate; +				len = a52_syncinfo(_inBuf, &_flags, &sampleRate, &bitRate); +				if (len == 0) { +					memmove(_inBuf, _inBuf + 1, HEADER_SIZE - 1); +					_inBufPtr--; +				} else { +					_frameSize = len;  				} -				outputPtr += 512; -				outputLength += 1024;  			} -		} -		if (outputLength > 0) { -			_audStream->queueBuffer((byte *)outputBuffer, outputLength, DisposeAfterUse::YES, Audio::FLAG_STEREO); +		} else if (len < _frameSize) { +			len = _frameSize - len; +			if (len > leftSize) +				len = leftSize; + +			assert(len < sizeof(_inBuf) - (_inBufPtr - _inBuf)); +			packet->read(_inBufPtr, len); +			leftSize -= len; +			_inBufPtr += len; +		} else { +			int flags = A52_STEREO | A52_ADJUST_LEVEL; +			sample_t level = 32767; + +			if (a52_frame(_a52State, _inBuf, &flags, &level, 0) != 0) +				error("Frame fail"); + +			int16 *outputBuffer = (int16 *)malloc(6 * 256 * 2 * 2); +			int16 *outputPtr = outputBuffer; +			int outputLength = 0; +			for (int i = 0; i < 6; i++) { +				if (a52_block(_a52State) == 0) { +					sample_t *samples = a52_samples(_a52State); +					for (int j = 0; j < 256; j++) { +						*outputPtr++ = (int16)samples[j]; +						*outputPtr++ = (int16)samples[j + 256]; +					} + +					outputLength += 1024; +				} +			} + +			if (outputLength > 0) { +				flags = Audio::FLAG_STEREO | Audio::FLAG_16BITS; + +#ifdef SCUMM_LITTLE_ENDIAN +				flags |= Audio::FLAG_LITTLE_ENDIAN; +#endif + +				_audStream->queueBuffer((byte *)outputBuffer, outputLength, DisposeAfterUse::YES, flags); +			} + +			_inBufPtr = _inBuf; +			_frameSize = 0;  		}  	} - -	delete[] buf;  }  #endif diff --git a/video/mpegps_decoder.h b/video/mpegps_decoder.h index 39b3a47af9..bf9c28e952 100644 --- a/video/mpegps_decoder.h +++ b/video/mpegps_decoder.h @@ -148,8 +148,11 @@ private:  	private:  		Audio::QueuingAudioStream *_audStream;  		a52_state_t *_a52State; +		uint32 _frameSize; +		byte _inBuf[4096]; +		byte *_inBufPtr; +		int _flags;  		int _sampleRate; -		int _packetLength;  		void initStream(Common::SeekableReadStream *packet);  		void decodeAC3Data(Common::SeekableReadStream *packet); | 
