aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--video/mpegps_decoder.cpp104
-rw-r--r--video/mpegps_decoder.h5
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);