Index: dsfilters/demux_mpc/src/mpc_file.cpp
===================================================================
--- dsfilters/demux_mpc/src/mpc_file.cpp	(revision 366)
+++ dsfilters/demux_mpc/src/mpc_file.cpp	(revision 367)
@@ -19,5 +19,7 @@
 	duration_10mhz(0),
 	reader(NULL),
-	packet(NULL)
+	packet(NULL),
+	seek_table(NULL),
+	seek_table_position(0)
 {
 	key = 0;
@@ -31,4 +33,8 @@
 CMPCFile::~CMPCFile()
 {
+	if (seek_table) {
+		free(seek_table);
+		seek_table = NULL;
+	}
 	if (packet) {
 		free(packet);
@@ -42,4 +48,5 @@
 	HRESULT		hr;
 	int			ret;
+	bool		done;
 
 	// keep a local copy of the reader
@@ -47,7 +54,5 @@
 
 
-	/*
-		According to stream specification the first 4 bytes should be 'MPCK'
-	*/
+	// According to stream specification the first 4 bytes should be 'MPCK'
 	uint32	magick;
 	reader->Seek(0);
@@ -58,7 +63,13 @@
 	}
 
+	// means no seek table
+	seek_table_position = 0;
+	seek_table_size = 0;
+
+	done = false;
+
 	// now loop through a few packets
 	do {
-		int ret = ReadNextPacket();
+		ret = ReadNextPacket();
 		if (ret < 0) return -1;			// end of file reached before initialization is done ?
 
@@ -66,14 +77,19 @@
 		case MPC_KEY('S','H'):	ret = ReadStreamHeader(); break;
 		case MPC_KEY('R','G'):  ret = ReadReplaygain(); break;
-
-		// TODO: Seek Table
+		case MPC_KEY('S','O'):	ret = ReadSeekOffset(); break;
 
 		// audio packet - initialization is over
-		case MPC_KEY('A','P'):	return 0;
+		case MPC_KEY('A','P'):	done = true; break;
 		}
 
 		// if parsing failed we quit
 		if (ret < 0) return ret;
-	} while (1);
+	} while (!done);
+
+	// if there was a seek table, load it
+	if (seek_table_position != 0) {
+		ret = ReadSeekTable(); 
+		if (ret < 0) return ret;
+	}
 
 	return 0;
@@ -86,5 +102,7 @@
 	int32	size_len;
 	int		ret;
-
+	int64	avail;
+
+	reader->GetPosition(&packet_pos, &avail);
 	ret = reader->GetKey(key_val);					if (ret < 0) return ret;
 	ret = reader->GetSizeElm(size_val, size_len);	if (ret < 0) return ret;
@@ -96,6 +114,4 @@
 	// size_val is the total size including key, variable size field and payload
 	packet_size = size_val - 2 - size_len;
-
-	// !!!!
 	ASSERT(packet_size <= packet_max_size);
 
@@ -123,4 +139,53 @@
 }
 
+int CMPCFile::ReadSeekOffset()
+{
+	Bitstream	b(packet);
+
+	seek_table_position = b.GetMpcSize();
+	seek_table_position += packet_pos;
+
+	// success 
+	return 0;
+}
+
+int CMPCFile::ReadSeekTable()
+{
+	reader->Seek(seek_table_position);
+	int ret;
+
+	ret = ReadNextPacket();
+	if (ret < 0) return ret;
+
+	Bitstream	b(packet);
+
+	// calculate size as seen in mpc_demux.c
+	int64 tmp = b.GetMpcSize();	b.NeedBits();
+	seek_table_size = tmp;
+	int	seek_pwr = block_pwr + b.UGetBits(4);
+	tmp = 2+total_samples / (1152 << seek_pwr);
+	if (tmp < seek_table_size) tmp = seek_table_size;
+
+	// alloc memory for seek table
+	seek_table = (uint32*)malloc(tmp * sizeof(uint32));
+
+	uint32 *table = seek_table;
+
+	tmp = b.GetMpcSize();
+	table[0] = (uint32)(tmp + header_position) * 8;
+	if (seek_table_size == 1) return 0;
+
+	tmp = b.GetMpcSize();
+	table[1] = (uint32)(tmp + header_position) * 8;
+	for (int i=2; i<seek_table_size; i++) {
+		int code = b.Get_Golomb(12);
+		if (code&1) code = -(code&(-1 << 1));
+		code <<= 2;
+		table[i] = code + 2*table[i-1] - table[i-2];
+	}
+
+	return 0;
+}
+
 int CMPCFile::ReadStreamHeader()
 {
@@ -157,5 +222,5 @@
 			//	Stream Version 8
 			//-----------------------------------------------------------------
-			int64	samples = b.GetMpcSize();
+			total_samples = b.GetMpcSize();
 			int64	silence = b.GetMpcSize();
 
@@ -173,5 +238,5 @@
 
 			// let's calculate duration
-			duration_10mhz = (samples * 10000000) / sample_rate;
+			duration_10mhz = (total_samples * 10000000) / sample_rate;
 
 			b.DumpBits(5);					// bands
@@ -180,6 +245,9 @@
 			b.NeedBits();
 			b.DumpBits(1);					// mid side
-			int exp = b.UGetBits(3);
-			audio_block_frames = 1 << (2*exp);
+			block_pwr = b.UGetBits(3) * 2;
+			audio_block_frames = 1 << (block_pwr);
+
+			// store absolute position of stream header
+			header_position = packet_pos;
 		}
 		break;
