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 /video | |
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.
Diffstat (limited to 'video')
-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); |