VIDEO: Use the standalone AC-3 decoder in the MPEG-PS code
This code comes from clone2727's now defunct (?) ac3 branch, with some minor compile fixes. This represents the latest version of the stalled AC-3 decoder work for Zork: Grand Inquisitor. Note, however, that I have not yet asked for clone2727's permission to use this. I'm just experimenting.
This commit is contained in:
parent
6705b6df9e
commit
43b29a93d7
2 changed files with 15 additions and 136 deletions
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "audio/audiostream.h"
|
||||
#include "audio/decoders/ac3.h"
|
||||
#include "audio/decoders/mp3.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/endian.h"
|
||||
|
@ -118,7 +119,7 @@ void MPEGPSDecoder::readNextPacket() {
|
|||
|
||||
#ifdef USE_A52
|
||||
handled = true;
|
||||
AC3AudioTrack *ac3Track = new AC3AudioTrack(packet);
|
||||
AC3AudioTrack *ac3Track = new AC3AudioTrack(*packet, getSoundType());
|
||||
stream = ac3Track;
|
||||
_streamMap[startCode] = ac3Track;
|
||||
addTrack(ac3Track);
|
||||
|
@ -545,35 +546,24 @@ Audio::AudioStream *MPEGPSDecoder::MPEGAudioTrack::getAudioStream() const {
|
|||
|
||||
#ifdef USE_A52
|
||||
|
||||
MPEGPSDecoder::AC3AudioTrack::AC3AudioTrack(Common::SeekableReadStream *firstPacket) {
|
||||
// In theory, I should pass mm_accel() to a52_init(), but I don't know
|
||||
// where that's supposed to be defined.
|
||||
_a52State = a52_init(0);
|
||||
|
||||
initStream(firstPacket);
|
||||
if (_sampleRate >= 0) {
|
||||
_audStream = Audio::makeQueuingAudioStream(_sampleRate, true);
|
||||
} else {
|
||||
_audStream = 0;
|
||||
}
|
||||
|
||||
firstPacket->seek(0);
|
||||
|
||||
_inBufPtr = _inBuf;
|
||||
_flags = 0;
|
||||
_frameSize = 0;
|
||||
MPEGPSDecoder::AC3AudioTrack::AC3AudioTrack(Common::SeekableReadStream &firstPacket, Audio::Mixer::SoundType soundType) :
|
||||
AudioTrack(soundType) {
|
||||
_audStream = Audio::makeAC3Stream(firstPacket);
|
||||
if (!_audStream)
|
||||
error("Could not create AC-3 stream");
|
||||
}
|
||||
|
||||
MPEGPSDecoder::AC3AudioTrack::~AC3AudioTrack() {
|
||||
delete _audStream;
|
||||
a52_free(_a52State);
|
||||
}
|
||||
|
||||
bool MPEGPSDecoder::AC3AudioTrack::sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts) {
|
||||
if (_audStream) {
|
||||
decodeAC3Data(packet);
|
||||
}
|
||||
delete packet;
|
||||
// Skip DVD code
|
||||
packet->readUint32LE();
|
||||
if (packet->eos())
|
||||
return true;
|
||||
|
||||
_audStream->queuePacket(packet);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -581,103 +571,6 @@ Audio::AudioStream *MPEGPSDecoder::AC3AudioTrack::getAudioStream() const {
|
|||
return _audStream;
|
||||
}
|
||||
|
||||
enum {
|
||||
HEADER_SIZE = 7
|
||||
};
|
||||
|
||||
void MPEGPSDecoder::AC3AudioTrack::initStream(Common::SeekableReadStream *packet) {
|
||||
byte buf[HEADER_SIZE];
|
||||
|
||||
_sampleRate = -1;
|
||||
|
||||
// Probably not very efficient, but hopefully we never do more than a
|
||||
// few iterations of this loop.
|
||||
for (uint i = 0; i < packet->size() - sizeof(buf); i++) {
|
||||
int flags, bitRate;
|
||||
|
||||
packet->seek(i, SEEK_SET);
|
||||
packet->read(buf, sizeof(buf));
|
||||
|
||||
if (a52_syncinfo(buf, &flags, &_sampleRate, &bitRate) > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MPEGPSDecoder::AC3AudioTrack::decodeAC3Data(Common::SeekableReadStream *packet) {
|
||||
// Skip the DVD code
|
||||
packet->readUint32LE();
|
||||
if (packet->eos())
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // End of namespace Video
|
||||
|
|
|
@ -28,11 +28,6 @@
|
|||
#include "graphics/surface.h"
|
||||
#include "video/video_decoder.h"
|
||||
|
||||
#ifdef USE_A52
|
||||
extern "C" {
|
||||
#include <a52dec/a52.h>
|
||||
}
|
||||
|
||||
namespace Audio {
|
||||
class PacketizedAudioStream;
|
||||
}
|
||||
|
@ -136,7 +131,7 @@ private:
|
|||
#ifdef USE_A52
|
||||
class AC3AudioTrack : public AudioTrack, public MPEGStream {
|
||||
public:
|
||||
AC3AudioTrack(Common::SeekableReadStream *firstPacket);
|
||||
AC3AudioTrack(Common::SeekableReadStream &firstPacket, Audio::Mixer::SoundType soundType);
|
||||
~AC3AudioTrack();
|
||||
|
||||
bool sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts);
|
||||
|
@ -146,16 +141,7 @@ private:
|
|||
Audio::AudioStream *getAudioStream() const;
|
||||
|
||||
private:
|
||||
Audio::QueuingAudioStream *_audStream;
|
||||
a52_state_t *_a52State;
|
||||
uint32 _frameSize;
|
||||
byte _inBuf[4096];
|
||||
byte *_inBufPtr;
|
||||
int _flags;
|
||||
int _sampleRate;
|
||||
|
||||
void initStream(Common::SeekableReadStream *packet);
|
||||
void decodeAC3Data(Common::SeekableReadStream *packet);
|
||||
Audio::PacketizedAudioStream *_audStream;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue