[Scummvm-cvs-logs] SF.net SVN: scummvm:[49900] scummvm/trunk/graphics/video

tdhs at users.sourceforge.net tdhs at users.sourceforge.net
Wed Jun 16 06:47:18 CEST 2010


Revision: 49900
          http://scummvm.svn.sourceforge.net/scummvm/?rev=49900&view=rev
Author:   tdhs
Date:     2010-06-16 04:47:18 +0000 (Wed, 16 Jun 2010)

Log Message:
-----------
Fixed QDM2 to working state.

Major issue was that the input frames are reused 16 times to produce output frames.
Thanks to clone2727 for helping with this.

Modified Paths:
--------------
    scummvm/trunk/graphics/video/codecs/qdm2.cpp
    scummvm/trunk/graphics/video/qt_decoder.cpp

Modified: scummvm/trunk/graphics/video/codecs/qdm2.cpp
===================================================================
--- scummvm/trunk/graphics/video/codecs/qdm2.cpp	2010-06-16 04:34:44 UTC (rev 49899)
+++ scummvm/trunk/graphics/video/codecs/qdm2.cpp	2010-06-16 04:47:18 UTC (rev 49900)
@@ -157,7 +157,7 @@
 	~QDM2Stream();
 
 	bool isStereo() const { return _channels == 2; }
-	bool endOfData() const { return ((_stream->pos() == _stream->size()) && (_outputSamples.size() == 0)); }
+	bool endOfData() const { return _stream->pos() >= _stream->size() && _outputSamples.size() == 0 && _subPacket == 0; }
 	int getRate() const { return _sampleRate; }
 	int readBuffer(int16 *buffer, const int numSamples);
 
@@ -199,7 +199,7 @@
 	int _fftCoefsMinIndex[5];
 	int _fftCoefsMaxIndex[5];
 	int _fftLevelExp[6];
-	//RDFTContext _rdftCtx;
+	RDFTContext _rdftCtx;
 	QDM2FFT _fft;
 
 	// I/O data
@@ -230,6 +230,7 @@
 	int _doSynthFilter;      // used to perform or skip synthesis filter
 
 	uint8 _subPacket; // 0 to 15
+	uint32 _superBlockStart;
 	int _noiseIdx; // index for dithering noise table
 
 	byte _emptyBuffer[FF_INPUT_BUFFER_PADDING_SIZE];
@@ -261,8 +262,6 @@
 	float _noiseSamples[128];
 	void initNoiseSamples(void);
 
-	RDFTContext _rdftCtx;
-
 	void average_quantized_coeffs(void);
 	void build_sb_samples_from_noise(int sb);
 	void fix_coding_method_array(int sb, int channels, sb_int8_array coding_method);
@@ -331,8 +330,6 @@
 static inline void initGetBits(GetBitContext *s, const uint8 *buffer, int bitSize) {
 	int bufferSize = (bitSize + 7) >> 3;
 
-	debug(1, "void initGetBits(GetBitContext *s, const uint8 *buffer, int bitSize)");
-
 	if (bufferSize < 0 || bitSize < 0) {
 		bufferSize = bitSize = 0;
 		buffer = NULL;
@@ -345,7 +342,6 @@
 }
 
 static inline int getBitsCount(GetBitContext *s) {
-	debug(1, "int getBitsCount(GetBitContext *s)");
 	return s->index;
 }
 
@@ -353,13 +349,9 @@
 	int index;
 	uint8 result;
 
-	debug(1, "unsigned int getBits1(GetBitContext *s)");
-
 	index = s->index;
 	result = s->buffer[index >> 3];
 
-	debug(1, "index : %d", index);
-
 	result >>= (index & 0x07);
 	result &= 1;
 	index++;
@@ -371,12 +363,8 @@
 static inline unsigned int getBits(GetBitContext *s, int n) {
 	int tmp, reCache, reIndex;
 
-	debug(1, "unsigned int getBits(GetBitContext *s, int n)");
-
 	reIndex = s->index;
 
-	debug(1, "reIndex : %d", reIndex);
-
 	reCache = READ_LE_UINT32((const uint8 *)s->buffer + (reIndex >> 3)) >> (reIndex & 0x07);
 
 	tmp = (reCache) & ((uint32)0xffffffff >> (32 - n));
@@ -389,13 +377,9 @@
 static inline void skipBits(GetBitContext *s, int n) {
 	int reIndex, reCache;
 
-	debug(1, "void skipBits(GetBitContext *s, int n)");
-
 	reIndex = s->index;
 	reCache = 0;
 
-	debug(1, "reIndex : %d", reIndex);
-
 	reCache = READ_LE_UINT32((const uint8 *)s->buffer + (reIndex >> 3)) >> (reIndex & 0x07);
 	s->index = reIndex + n;
 }
@@ -1331,20 +1315,12 @@
 	int code;
 	int n;
 
-	debug(1, "int getVlc2(GetBitContext *s, int16 (*table)[2], int bits, int maxDepth)");
-
 	reIndex = s->index;
 	reCache = READ_LE_UINT32(s->buffer + (reIndex >> 3)) >> (reIndex & 0x07);
 	index = reCache & (0xffffffff >> (32 - bits));
 	code = table[index][0];
 	n = table[index][1];
 
-	debug(1, "reIndex : %d", reIndex);
-	debug(1, "reCache : %d", reCache);
-	debug(1, "index : %d", index);
-	debug(1, "code : %d", code);
-	debug(1, "n : %d", n);
-
 	if (maxDepth > 1 && n < 0){
 		reIndex += bits;
 		reCache = READ_LE_UINT32(s->buffer + (reIndex >> 3)) >> (reIndex & 0x07);
@@ -1416,7 +1392,6 @@
 
 	table_size = 1 << table_nb_bits;
 	table_index = allocTable(vlc, table_size, flags & 4);
-	debug(2, "QDM2 new table index=%d size=%d code_prefix=%x n=%d", table_index, table_size, code_prefix, n_prefix);
 	if (table_index < 0)
 		return -1;
 	table = &vlc->table[table_index];
@@ -1437,7 +1412,6 @@
 			symbol = i;
 		else
 			GET_DATA(symbol, symbols, i, symbols_wrap, symbols_size);
-		debug(2, "QDM2 i=%d n=%d code=0x%x", i, n, code);
 		// if code matches the prefix, it is in the table
 		n -= n_prefix;
 		if(flags & 2)
@@ -1452,7 +1426,6 @@
 				for(k = 0; k < nb; k++) {
 					if(flags & 2)
 						j = (code >> n_prefix) + (k<<n);
-					debug(2, "QDM2 %4x: code=%d n=%d",j, i, n);
 					if (table[j][1] /*bits*/ != 0) {
 						error("QDM2 incorrect codes");
 						return -1;
@@ -1464,7 +1437,6 @@
 			} else {
 				n -= table_nb_bits;
 				j = (code >> ((flags & 2) ? n_prefix : n)) & ((1 << table_nb_bits) - 1);
-				debug(2, "QDM2 %4x: n=%d (subtable)", j, n);
 				// compute table size
 				n1 = -table[j][1]; //bits
 				if (n > n1)
@@ -1537,8 +1509,6 @@
 		error("called on a partially initialized table");
 	}
 
-	debug(2, "QDM2 build table nb_codes=%d", nb_codes);
-
 	if (build_table(vlc, nb_bits, nb_codes,
 	                bits, bits_wrap, bits_size,
 	                codes, codes_wrap, codes_size,
@@ -1754,6 +1724,7 @@
 	_stream = stream;
 	_compressedData = NULL;
 	_subPacket = 0;
+	_superBlockStart = 0;
 	memset(_quantizedCoeffs, 0, sizeof(_quantizedCoeffs));
 	memset(_fftLevelExp, 0, sizeof(_fftLevelExp));
 	_noiseIdx = 0;
@@ -2015,8 +1986,6 @@
 
 		sub_packet->data = &gb->buffer[getBitsCount(gb) / 8]; // FIXME: this depends on bitreader internal data
 	}
-
-	debug(1, "QDM2 Subpacket: type=%d size=%d start_offs=%x", sub_packet->type, sub_packet->size, getBitsCount(gb) / 8);
 }
 
 /**
@@ -2881,7 +2850,6 @@
 }
 
 void QDM2Stream::qdm2_fft_decode_tones(int duration, GetBitContext *gb, int b) {
-	debug(1, "QDM2Stream::qdm2_fft_decode_tones() duration: %d b:%d", duration, b);
 	int channel, stereo, phase, exp;
 	int local_int_4,  local_int_8,  stereo_phase,  local_int_10;
 	int local_int_14, stereo_exp, local_int_20, local_int_28;
@@ -2896,9 +2864,7 @@
 
 	while (1) {
 		if (_superblocktype_2_3) {
-			debug(1, "QDM2Stream::qdm2_fft_decode_tones() local_int_8: %d", local_int_8);
 			while ((n = qdm2_get_vlc(gb, &_vlcTabFftToneOffset[local_int_8], 1, 2)) < 2) {
-				debug(1, "QDM2Stream::qdm2_fft_decode_tones() local_int_8: %d", local_int_8);
 				offset = 1;
 				if (n == 0) {
 					local_int_4 += local_int_10;
@@ -2959,7 +2925,6 @@
 }
 
 void QDM2Stream::qdm2_decode_fft_packets(void) {
-	debug(1, "QDM2Stream::qdm2_decode_fft_packets()");
 	int i, j, min, max, value, type, unknown_flag;
 	GetBitContext gb;
 
@@ -2994,7 +2959,6 @@
 			return;
 
 		// decode FFT tones
-		debug(1, "QDM2Stream::qdm2_decode_fft_packets initGetBits() packet->size*8: %d", packet->size*8);
 		initGetBits(&gb, packet->data, packet->size*8);
 
 		if (packet->type >= 32 && packet->type < 48 && !fft_subpackets[packet->type - 16])
@@ -3008,19 +2972,16 @@
 			int duration = _subSampling + 5 - (type & 15);
 
 			if (duration >= 0 && duration < 4) { // TODO: Should be <= 4?
-				debug(1, "QDM2Stream::qdm2_decode_fft_packets qdm2_fft_decode_tones() #1");
 				qdm2_fft_decode_tones(duration, &gb, unknown_flag);
 			}
 		} else if (type == 31) {
 			for (j=0; j < 4; j++) {
-				debug(1, "QDM2Stream::qdm2_decode_fft_packets qdm2_fft_decode_tones() #2");
 				qdm2_fft_decode_tones(j, &gb, unknown_flag);
 			}
 		} else if (type == 46) {
 			for (j=0; j < 6; j++)
 				_fftLevelExp[j] = getBits(&gb, 6);
 			for (j=0; j < 4; j++) {
-				debug(1, "QDM2Stream::qdm2_decode_fft_packets qdm2_fft_decode_tones() #3");
 				qdm2_fft_decode_tones(j, &gb, unknown_flag);
 			}
 		}
@@ -3151,16 +3112,12 @@
 }
 
 void QDM2Stream::qdm2_calculate_fft(int channel) {
-	debug(1, "QDM2Stream::qdm2_calculate_fft channel: %d", channel);
 	const float gain = (_channels == 1 && _channels == 2) ? 0.5f : 1.0f;
 	int i;
 
 	_fft.complex[channel][0].re *= 2.0f;
 	_fft.complex[channel][0].im = 0.0f;
 
-	//debug(1, "QDM2Stream::qdm2_calculate_fft _fft.complex[channel][0].re: %lf", _fft.complex[channel][0].re);
-	//debug(1, "QDM2Stream::qdm2_calculate_fft _fft.complex[channel][0].im: %lf", _fft.complex[channel][0].im);
-
 	rdftCalc(&_rdftCtx, (float *)_fft.complex[channel]);
 
 	// add samples to output buffer
@@ -3209,82 +3166,80 @@
 	int ch, i;
 	const int frame_size = (_sFrameSize * _channels);
 
+	// If we're in any packet but the first, seek back to the first
+	if (_subPacket == 0)
+		_superBlockStart = in->pos();
+	else
+		in->seek(_superBlockStart);
+
 	// select input buffer
-	if(in->eos() || in->size() == in->pos()) {
+	if (in->eos() || in->pos() >= in->size()) {
 		debug(1, "QDM2Stream::qdm2_decodeFrame End of Input Stream");
 		return 0;
 	}
-	if((in->size() - in->pos()) < _packetSize) {
+
+	if ((in->size() - in->pos()) < _packetSize) {
 		debug(1, "QDM2Stream::qdm2_decodeFrame Insufficient Packet Data in Input Stream Found: %d Need: %d", in->size() - in->pos(), _packetSize);
 		return 0;
 	}
 
-	in->read(_compressedData, _packetSize);
-	debug(1, "QDM2Stream::qdm2_decodeFrame constructed input data");
+	if (!in->eos()) {
+		in->read(_compressedData, _packetSize);
+		debug(1, "QDM2Stream::qdm2_decodeFrame constructed input data");
+	}
 
 	// copy old block, clear new block of output samples
 	memmove(_outputBuffer, &_outputBuffer[frame_size], frame_size * sizeof(float));
 	memset(&_outputBuffer[frame_size], 0, frame_size * sizeof(float));
 	debug(1, "QDM2Stream::qdm2_decodeFrame cleared outputBuffer");
 
-	// decode block of QDM2 compressed data
-	debug(1, "QDM2Stream::qdm2_decodeFrame decode block of QDM2 compressed data");
-	if (_subPacket == 0) {
-		_hasErrors = false; // reset it for a new super block
-		debug(1, "QDM2 : Superblock follows");
-		qdm2_decode_super_block();
-	}
-
-	// parse subpackets
-	debug(1, "QDM2Stream::qdm2_decodeFrame parse subpackets");
-	if (!_hasErrors) {
-		if (_subPacket == 2) {
-			debug(1, "QDM2Stream::qdm2_decodeFrame qdm2_decode_fft_packets()");
-			qdm2_decode_fft_packets();
+	if (!in->eos()) {
+		// decode block of QDM2 compressed data
+		debug(1, "QDM2Stream::qdm2_decodeFrame decode block of QDM2 compressed data");
+		if (_subPacket == 0) {
+			_hasErrors = false; // reset it for a new super block
+			debug(1, "QDM2 : Superblock follows");
+			qdm2_decode_super_block();
 		}
 
-		debug(1, "QDM2Stream::qdm2_decodeFrame qdm2_fft_tone_synthesizer(%d)", _subPacket);
-		qdm2_fft_tone_synthesizer(_subPacket);
-	}
+		// parse subpackets
+		debug(1, "QDM2Stream::qdm2_decodeFrame parse subpackets");
+		if (!_hasErrors) {
+			if (_subPacket == 2) {
+				debug(1, "QDM2Stream::qdm2_decodeFrame qdm2_decode_fft_packets()");
+				qdm2_decode_fft_packets();
+			}
 
-	// sound synthesis stage 1 (FFT)
-	debug(1, "QDM2Stream::qdm2_decodeFrame sound synthesis stage 1 (FFT)");
-	for (ch = 0; ch < _channels; ch++) {
-		qdm2_calculate_fft(ch);
-
-		if (!_hasErrors && _subPacketListC[0].packet != NULL) {
-			error("QDM2 : has errors, and C list is not empty");
-			return 0;
+			debug(1, "QDM2Stream::qdm2_decodeFrame qdm2_fft_tone_synthesizer(%d)", _subPacket);
+			qdm2_fft_tone_synthesizer(_subPacket);
 		}
-	}
 
-	// sound synthesis stage 2 (MPEG audio like synthesis filter)
-	debug(1, "QDM2Stream::qdm2_decodeFrame sound synthesis stage 2 (MPEG audio like synthesis filter)");
-	if (!_hasErrors && _doSynthFilter)
-		qdm2_synthesis_filter(_subPacket);
+		// sound synthesis stage 1 (FFT)
+		debug(1, "QDM2Stream::qdm2_decodeFrame sound synthesis stage 1 (FFT)");
+		for (ch = 0; ch < _channels; ch++) {
+			qdm2_calculate_fft(ch);
 
-	_subPacket = (_subPacket + 1) % 16;
+			if (!_hasErrors && _subPacketListC[0].packet != NULL) {
+				error("QDM2 : has errors, and C list is not empty");
+				return 0;
+			}
+		}
 
-	if(_hasErrors)
-		warning("QDM2 Packet error...");
+		// sound synthesis stage 2 (MPEG audio like synthesis filter)
+		debug(1, "QDM2Stream::qdm2_decodeFrame sound synthesis stage 2 (MPEG audio like synthesis filter)");
+		if (!_hasErrors && _doSynthFilter)
+			qdm2_synthesis_filter(_subPacket);
 
-	// clip and convert output float[] to 16bit signed samples
-	debug(1, "QDM2Stream::qdm2_decodeFrame clip and convert output float[] to 16bit signed samples");
+		_subPacket = (_subPacket + 1) % 16;
 
-/*
-	debugN(1, "Input Data Packet:");
-	for(i = 0; i < _packetSize; i++) {
-		debugN(1, " %d", _compressedData[i]);
+		if(_hasErrors)
+			warning("QDM2 Packet error...");
+
+		// clip and convert output float[] to 16bit signed samples
+		debug(1, "QDM2Stream::qdm2_decodeFrame clip and convert output float[] to 16bit signed samples");
 	}
-	debugN(1, " Output Data Packet:");
-	for(i = 0; i < frame_size; i++) {
-		debugN(1, " %d", (int)_outputBuffer[i]);
-	}
-	debug(1, "");
-*/
 
 	for (i = 0; i < frame_size; i++) {
-		//debug(1, "QDM2Stream::qdm2_decodeFrame i: %d", i);
 		int value = (int)_outputBuffer[i];
 
 		if (value > SOFTCLIP_THRESHOLD)
@@ -3302,17 +3257,17 @@
 	int32 decodedSamples = _outputSamples.size();
 	int32 i;
 
-	//while((int)_outputSamples.size() < numSamples) {
-	while(!_stream->eos() && _stream->pos() != _stream->size()) {
+	while (decodedSamples < numSamples) {
 		i = qdm2_decodeFrame(_stream);
-		if(i == 0)
+		if (i == 0)
 			break; // Out Of Decode Frames...
 		decodedSamples += i;
 	}
-	if(decodedSamples > numSamples)
+
+	if (decodedSamples > numSamples)
 		decodedSamples = numSamples;
 
-	for(i = 0; i < decodedSamples; i++)
+	for (i = 0; i < decodedSamples; i++)
 		buffer[i] = _outputSamples.remove_at(0);
 
 	return decodedSamples;

Modified: scummvm/trunk/graphics/video/qt_decoder.cpp
===================================================================
--- scummvm/trunk/graphics/video/qt_decoder.cpp	2010-06-16 04:34:44 UTC (rev 49899)
+++ scummvm/trunk/graphics/video/qt_decoder.cpp	2010-06-16 04:47:18 UTC (rev 49900)
@@ -191,8 +191,10 @@
 }
 
 void QuickTimeDecoder::startAudio() {
-	if (_audStream) // No audio/audio not supported
+	if (_audStream) { // No audio/audio not supported
+		updateAudioBuffer();
 		g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audHandle, _audStream);
+	}
 }
 
 void QuickTimeDecoder::stopAudio() {


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list