aboutsummaryrefslogtreecommitdiff
path: root/video
diff options
context:
space:
mode:
authorTorbjörn Andersson2015-08-04 19:14:03 +0200
committerThierry Crozat2018-11-04 22:33:22 +0100
commitad41dfb7ff25daf9e974c6c9dbdfb099307af4f7 (patch)
treeb4140153134a84d73ec7dd8af9827cbc09756e4f /video
parente9052a008578b42ca5f5e869ef9e6ebe969cb929 (diff)
downloadscummvm-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.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);