Index: /dsfilters/before-you-ask.txt
===================================================================
--- /dsfilters/before-you-ask.txt	(revision 366)
+++ /dsfilters/before-you-ask.txt	(revision 366)
@@ -0,0 +1,18 @@
+This package is developed with Visual Studio 2005.
+If you get an error like
+
+"Application cannot start" 
+
+or similar, go to microsoft.com
+and download Visual C++ 2005 SP1 Redistributable Package.
+It's about 2.6 MB large and contains required DLLs.
+In time I'll try to get a VC++ 2003 and build.
+
+Right now the only working filter is the demux_mpc.
+But it does not actually output data. Only analyzes input
+and displays information in property page.
+Internal delivery mechanism and buffering is already implemented.
+
+stay tuned.
+
+Igor.
Index: /dsfilters/demux_mpc/demux_mpc.def
===================================================================
--- /dsfilters/demux_mpc/demux_mpc.def	(revision 366)
+++ /dsfilters/demux_mpc/demux_mpc.def	(revision 366)
@@ -0,0 +1,6 @@
+LIBRARY         mmmpcdmx.ax
+EXPORTS
+	DllGetClassObject		PRIVATE
+	DllCanUnloadNow			PRIVATE
+	DllRegisterServer		PRIVATE
+	DllUnregisterServer		PRIVATE
Index: /dsfilters/demux_mpc/demux_mpc.rc
===================================================================
--- /dsfilters/demux_mpc/demux_mpc.rc	(revision 366)
+++ /dsfilters/demux_mpc/demux_mpc.rc	(revision 366)
@@ -0,0 +1,130 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Slovak resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_SKY)
+#ifdef _WIN32
+LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT
+#pragma code_page(1250)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_BMP_LOGO            BITMAP                  "bitmap_logo.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE 
+BEGIN
+    IDS_PAGE_DEMUX          "Musepack File"
+END
+
+#endif    // Slovak resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_PAGE_DEMUX DIALOGEX 0, 0, 280, 194
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+    CTEXT           "This free software is released under the GNU GPL license.",IDC_STATIC,6,150,120,18
+    CTEXT           "http://www.musepack.net",IDC_STATIC,6,174,120,8
+    CTEXT           "DirectShow filter implemented by RadScorpion",IDC_STATIC,150,150,120,18
+    CTEXT           "http://blog.monogram.sk/janos",IDC_STATIC,150,174,120,8
+    CONTROL         "",IDC_LIST_CONTENT,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_TABSTOP,6,36,264,108,WS_EX_CLIENTEDGE
+    CONTROL         101,IDC_STATIC,"Static",SS_BITMAP,0,0,280,30
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO 
+BEGIN
+    IDD_PAGE_DEMUX, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 273
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 187
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
Index: /dsfilters/demux_mpc/demux_mpc.sln
===================================================================
--- /dsfilters/demux_mpc/demux_mpc.sln	(revision 366)
+++ /dsfilters/demux_mpc/demux_mpc.sln	(revision 366)
@@ -0,0 +1,20 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demux_mpc", "demux_mpc.vcproj", "{17662646-020C-4374-AB81-BA2434AD8260}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{17662646-020C-4374-AB81-BA2434AD8260}.Debug|Win32.ActiveCfg = Debug|Win32
+		{17662646-020C-4374-AB81-BA2434AD8260}.Debug|Win32.Build.0 = Debug|Win32
+		{17662646-020C-4374-AB81-BA2434AD8260}.Release|Win32.ActiveCfg = Release|Win32
+		{17662646-020C-4374-AB81-BA2434AD8260}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: /dsfilters/demux_mpc/demux_mpc.vcproj
===================================================================
--- /dsfilters/demux_mpc/demux_mpc.vcproj	(revision 366)
+++ /dsfilters/demux_mpc/demux_mpc.vcproj	(revision 366)
@@ -0,0 +1,269 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="demux_mpc"
+	ProjectGUID="{17662646-020C-4374-AB81-BA2434AD8260}"
+	RootNamespace="demux_mpc"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			UseOfMFC="2"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories=".\src"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;DEMUX_MPC_EXPORTS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="strmbasdu.lib strmiids.lib winmm.lib"
+				OutputFile=".\bin\mmmpcdmxd.ax"
+				LinkIncremental="2"
+				ModuleDefinitionFile="demux_mpc.def"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				EntryPointSymbol="DllEntryPoint@12"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			UseOfMFC="2"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=".\src"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;DEMUX_MPC_EXPORTS"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="strmbaseu.lib strmiids.lib winmm.lib"
+				OutputFile=".\bin\mmmpcdmx.ax"
+				LinkIncremental="1"
+				ModuleDefinitionFile="demux_mpc.def"
+				GenerateDebugInformation="false"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				EntryPointSymbol="DllEntryPoint@12"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\src\bits.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\mpc_file.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\mpc_filter.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\mpc_pin.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\mpc_prop.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\mpc_reg.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\src\bits.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\mpc_file.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\mpc_filter.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\mpc_pin.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\mpc_prop.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\mpc_types.h"
+				>
+			</File>
+			<File
+				RelativePath=".\resource.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\stdafx.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+			<File
+				RelativePath=".\bitmap_logo.bmp"
+				>
+			</File>
+			<File
+				RelativePath=".\demux_mpc.rc"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: /dsfilters/demux_mpc/resource.h
===================================================================
--- /dsfilters/demux_mpc/resource.h	(revision 366)
+++ /dsfilters/demux_mpc/resource.h	(revision 366)
@@ -0,0 +1,19 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by demux_mpc.rc
+//
+#define IDB_BMP_LOGO                    101
+#define IDS_PAGE_DEMUX                  102
+#define IDD_PAGE_DEMUX                  105
+#define IDC_LIST_CONTENT                1001
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        103
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1002
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
Index: /dsfilters/demux_mpc/src/bits.cpp
===================================================================
--- /dsfilters/demux_mpc/src/bits.cpp	(revision 366)
+++ /dsfilters/demux_mpc/src/bits.cpp	(revision 366)
@@ -0,0 +1,114 @@
+//-----------------------------------------------------------------------------
+//
+//	Musepack Demuxer
+//
+//	Author : Igor Janos
+//
+//-----------------------------------------------------------------------------
+#include "stdafx.h"
+
+//-----------------------------------------------------------------------------
+//
+//	Bitstream class
+//
+//	podporuje citanie bitstreamu
+//
+//----------------------------------------------------------------------------
+
+const int32 Bitstream::EXP_GOLOMB_MAP[2][48] =
+{
+	{
+		47, 31, 15,  0, 23, 27, 29, 30,
+		 7, 11, 13, 14, 39, 43, 45, 46,
+		16,  3,  5, 10, 12, 19, 21, 26,
+		28, 35, 37, 42, 44,  1,  2,  4,
+		 8, 17, 18, 20, 24,  6,  9, 22,
+	    25, 32, 33, 34, 36, 40, 38, 41
+	},
+	{
+		 0, 16,  1,  2,  4,  8, 32,  3,
+	     5, 10, 12, 15, 47,  7, 11, 13,
+	    14,  6,  9, 31, 35, 37, 42, 44,
+		33, 34, 36, 40, 39, 43, 45, 46,
+		17, 18, 20, 24, 19, 21, 26, 28,
+		23, 27, 29, 30, 22, 25, 38, 41
+	}
+};
+
+const int32 Bitstream::EXP_GOLOMB_MAP_INV[2][48] =
+{
+	{
+		 3, 29, 30, 17, 31, 18, 37,  8,
+	    32, 38, 19,  9, 20, 10, 11,  2,
+		16, 33, 34, 21, 35, 22, 39,  4,
+		36, 40, 23,  5, 24,  6,  7,  1,
+		41, 42, 43, 25, 44, 26, 46, 12,
+		45, 47, 27, 13, 28, 14, 15,  0
+	},
+	{
+		 0,  2,  3,  7,  4,  8, 17, 13,
+	     5, 18,  9, 14, 10, 15, 16, 11,
+	     1, 32, 33, 36, 34, 37, 44, 40,
+	    35, 45, 38, 41, 39, 42, 43, 19,
+		 6, 24, 25, 20, 26, 21, 46, 28,
+	    27, 47, 22, 29, 23, 30, 31, 12 
+	}
+};
+
+
+// Exp-Golomb Codes
+
+const int32 Bitstream::EXP_GOLOMB_SIZE[255] =
+{
+    1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7,
+    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+    11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
+    11,11,11,11,11,11,11,11,11,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
+    13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
+    13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
+    13,13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+    15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+    15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+    15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+    15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+    15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15
+};
+
+uint32 Bitstream::Get_UE()
+{
+	int32 len = 0;
+	NeedBits24();
+	while (!UGetBits(1)) len++;
+	NeedBits24();
+	return (len == 0 ? 0 : (1<<len)-1 + UGetBits(len));
+}
+
+int32 Bitstream::Get_SE()
+{
+	int32 len = 0;
+	NeedBits24();
+	while (!UGetBits(1)) len++;
+	if (len == 0) return 0;
+	NeedBits24();
+	int32 val = (1 << len) | UGetBits(len);
+    return (val&1) ? -(val>>1) : (val>>1);
+}
+
+int32 Bitstream::Get_ME(int32 mode)
+{
+	// nacitame UE a potom podla mapovacej tabulky
+	int32 codeNum = Get_UE();
+	if (codeNum >= 48) return -1;		// chyba
+	return EXP_GOLOMB_MAP[mode][codeNum];
+}
+
+int32 Bitstream::Get_TE(int32 range)
+{
+	/* ISO/IEC 14496-10 - Section 9.1 */
+	if (range > 1) {
+		return Get_UE();
+	} else {
+		return (!UGetBits(1))&0x01;
+	}
+}
+
Index: /dsfilters/demux_mpc/src/bits.h
===================================================================
--- /dsfilters/demux_mpc/src/bits.h	(revision 366)
+++ /dsfilters/demux_mpc/src/bits.h	(revision 366)
@@ -0,0 +1,106 @@
+//-----------------------------------------------------------------------------
+//
+//	Musepack Demuxer
+//
+//	Author : Igor Janos
+//
+//-----------------------------------------------------------------------------
+#pragma once
+
+// well.. I just like those
+typedef unsigned char		uint8;
+typedef unsigned short		uint16;
+typedef unsigned int		uint32;
+typedef unsigned __int64	uint64;
+typedef signed char			int8;
+typedef signed short		int16;
+typedef signed int			int32;
+typedef signed __int64		int64;
+
+//-------------------------------------------------------------------------
+//
+//	Bitstream class
+//
+//-------------------------------------------------------------------------
+
+class Bitstream
+{
+public:
+	uint32	bitbuf;				// bitbuffer
+	uint8	*buf;				// byte buffer
+	int32	bits;				// pocet bitov v bitbufferi 
+
+public:
+	static const int32 EXP_GOLOMB_MAP[2][48];
+	static const int32 EXP_GOLOMB_MAP_INV[2][48];
+    static const int32 EXP_GOLOMB_SIZE[255];
+
+public:
+
+	// Konstruktory
+	Bitstream() : bitbuf(0), buf(NULL), bits(0) { };
+	Bitstream(uint8 *b) : bitbuf(0), buf(b), bits(0) { };
+	Bitstream(const Bitstream &b) : bitbuf(b.bitbuf), buf(b.buf), bits(b.bits) { };
+
+	// Operator priradenia = kopia stavu bitstreamu
+	Bitstream &operator =(const Bitstream &b) { bitbuf = b.bitbuf; buf = b.buf; bits = b.bits; return *this; };
+	Bitstream &operator =(const uint8 *b) { bitbuf = 0; buf = (uint8*)b; bits = 0; return *this; };
+	Bitstream &operator =(uint8 *b) { bitbuf = 0; buf = b; bits = 0; return *this; };
+
+	// Resetovanie stavu
+	inline void Init(const uint8 *b) { bitbuf = 0; buf = (uint8*)b; bits = 0; };
+	inline void Init(uint8 *b) { bitbuf = 0; buf = b; bits = 0; };
+
+	// Zistenie stavu bitstreamu
+	inline int32 BitsLeft() { return bits; };
+	inline uint32 BitBuf() { return bitbuf; };
+	inline uint8 *Position() { return buf - (bits/8); };
+
+	// Citanie z bitstreamu
+	inline void DumpBits(int32 n) { bitbuf <<= n; bits -= n; };
+	inline uint32 UBits(int32 n) { return (uint32)(bitbuf >> (32-n)); };
+	inline uint32 UGetBits(int32 n) { uint32 val = (uint32)(bitbuf >> (32-n)); bitbuf <<= n; bits -= n; return val; };
+	inline int32 SBits(int32 n) { return (int32)(bitbuf >> (32-n)); };
+	inline int32 SGetBits(int32 n) { int32 val = (int32)(bitbuf >> (32-n)); bitbuf <<= n; bits -= n; return val; };
+	inline void Markerbit() { DumpBits(1); }
+
+	// Reading variable length size field
+	inline int64 GetMpcSize() {
+		int64 ret=0;
+		uint8 tmp;
+		do {
+			NeedBits();
+			tmp = UGetBits(8);
+			ret = (ret<<7) | (tmp&0x7f);
+		} while (tmp&0x80);
+		return ret;
+	}
+
+	// Zarovnavanie na byty
+	inline int32 IsByteAligned() { return !(bits&0x07); };
+	inline void ByteAlign() { if (bits&0x07) DumpBits(bits&0x07); };
+
+	// Exp-Golomb Codes
+	uint32 Get_UE();
+	int32 Get_SE();
+	int32 Get_ME(int32 mode);
+	int32 Get_TE(int32 range);
+
+	inline int32 Size_UE(uint32 val) 
+	{
+		if (val<255) return EXP_GOLOMB_SIZE[val];
+		int32 isize=0;
+		val++;
+		if (val >= 0x10000) { isize+= 32;	val = (val >> 16)-1; }
+		if (val >= 0x100)	{ isize+= 16;	val = (val >> 8)-1;  }
+		return EXP_GOLOMB_SIZE[val] + isize;
+	}
+
+	inline int32 Size_SE(int32 val)				{ return Size_UE(val <= 0 ? -val*2 : val*2 - 1); }
+	inline int32 Size_TE(int32 range, int32 v)  { if (range == 1) return 1; return Size_UE(v);	}
+
+	// Loadovanie bitov do bitbufferu
+	inline void NeedBits() { if (bits < 16) { bitbuf |= ((buf[0] << 8) | (buf[1])) << (16-bits); bits += 16; buf += 2; } };
+	inline void NeedBits24() { while (bits<24) { bitbuf |= (buf[0] << (24-bits)); buf++; bits+= 8; } };
+	inline void NeedBits32() { while (bits<32) { bitbuf |= (buf[0] << (24-bits)); buf++; bits+= 8; } };
+};
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 366)
@@ -0,0 +1,195 @@
+//-----------------------------------------------------------------------------
+//
+//	Musepack Demuxer
+//
+//	Author : Igor Janos
+//
+//-----------------------------------------------------------------------------
+#include "stdafx.h"
+
+
+
+//-----------------------------------------------------------------------------
+//
+//	CMPCFile class
+//
+//-----------------------------------------------------------------------------
+
+CMPCFile::CMPCFile() :
+	duration_10mhz(0),
+	reader(NULL),
+	packet(NULL)
+{
+	key = 0;
+	packet_max_size = 512 * 1024;			// well. hard to say. but I think this should be enough
+	packet_size = 0;
+	packet = (uint8*)malloc(packet_max_size);
+
+	ASSERT(packet);
+}
+
+CMPCFile::~CMPCFile()
+{
+	if (packet) {
+		free(packet);
+		packet = NULL;
+	}
+}
+
+// I/O for MPC file
+int CMPCFile::Open(CMPCReader *reader)
+{
+	HRESULT		hr;
+	int			ret;
+
+	// keep a local copy of the reader
+	this->reader = reader;
+
+
+	/*
+		According to stream specification the first 4 bytes should be 'MPCK'
+	*/
+	uint32	magick;
+	reader->Seek(0);
+	ret = reader->GetMagick(magick);			if (ret < 0) return ret;
+	if (magick != 0x4d50434b) {
+		// not a Musepack file
+		return -1;
+	}
+
+	// now loop through a few packets
+	do {
+		int ret = ReadNextPacket();
+		if (ret < 0) return -1;			// end of file reached before initialization is done ?
+
+		switch (key) {
+		case MPC_KEY('S','H'):	ret = ReadStreamHeader(); break;
+		case MPC_KEY('R','G'):  ret = ReadReplaygain(); break;
+
+		// TODO: Seek Table
+
+		// audio packet - initialization is over
+		case MPC_KEY('A','P'):	return 0;
+		}
+
+		// if parsing failed we quit
+		if (ret < 0) return ret;
+	} while (1);
+
+	return 0;
+}
+
+int CMPCFile::ReadNextPacket()
+{
+	uint16	key_val;
+	int64	size_val;
+	int32	size_len;
+	int		ret;
+
+	ret = reader->GetKey(key_val);					if (ret < 0) return ret;
+	ret = reader->GetSizeElm(size_val, size_len);	if (ret < 0) return ret;
+
+	// if the key is not valid, quit
+	if (!reader->KeyValid(key_val)) return -1;
+	key = key_val;
+
+	// 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);
+
+	ret = reader->Read(packet, packet_size);		if (ret < 0) return ret;
+	return 0;
+}
+
+// parsing packets
+
+int CMPCFile::ReadReplaygain()
+{
+	Bitstream	b(packet);
+	b.NeedBits();
+
+	int version = b.UGetBits(8);
+	if (version != 1) return 0;		// unsupported RG version. not critical to us...
+
+	int16	val;
+	b.NeedBits();	val = b.SGetBits(16);	gain_title_db = val / 256.0;
+	b.NeedBits();	val = b.SGetBits(16);	gain_title_peak_db = val / 256.0;
+	b.NeedBits();	val = b.SGetBits(16);	gain_album_db = val / 256.0;
+	b.NeedBits();	val = b.SGetBits(16);	gain_album_peak_db = val / 256.0;
+
+	return 0;
+}
+
+int CMPCFile::ReadStreamHeader()
+{
+	Bitstream	b(packet);
+	b.NeedBits();
+
+	// let's do some reading
+	uint32		crc;
+	crc = b.UGetBits(16);	b.NeedBits();
+	crc <<= 16;
+	crc |= b.UGetBits(16);
+
+	// TODO: CRC checking.
+	b.NeedBits();
+	stream_version = b.UGetBits(8);
+
+	switch (stream_version) {
+	case 7:
+		{
+			//-----------------------------------------------------------------
+			//	Stream Version 7
+			//-----------------------------------------------------------------
+
+			// since we don't do any actual decoding here, we can only look 
+			// for the fields of our interest
+
+			// TODO: later. now we want SV8
+
+		}
+		break;
+	case 8:
+		{
+			//-----------------------------------------------------------------
+			//	Stream Version 8
+			//-----------------------------------------------------------------
+			int64	samples = b.GetMpcSize();
+			int64	silence = b.GetMpcSize();
+
+			b.NeedBits();
+			uint8	freq = b.UGetBits(3);
+			switch (freq) {
+			case 0:	sample_rate = 44100; break;
+			case 1:	sample_rate = 48000; break;
+			case 2:	sample_rate = 37800; break;
+			case 3: sample_rate = 32000; break;
+			default:
+				// invalid value
+				return -1;				
+			}
+
+			// let's calculate duration
+			duration_10mhz = (samples * 10000000) / sample_rate;
+
+			b.DumpBits(5);					// bands
+			channels = b.UGetBits(4)+1;		// channels
+
+			b.NeedBits();
+			b.DumpBits(1);					// mid side
+			int exp = b.UGetBits(3);
+			audio_block_frames = 1 << (2*exp);
+		}
+		break;
+	default:
+		// stream version not supported
+		return -2;
+	}
+
+	// everything is okay
+	return 0;
+}
+
+
Index: /dsfilters/demux_mpc/src/mpc_file.h
===================================================================
--- /dsfilters/demux_mpc/src/mpc_file.h	(revision 366)
+++ /dsfilters/demux_mpc/src/mpc_file.h	(revision 366)
@@ -0,0 +1,57 @@
+//-----------------------------------------------------------------------------
+//
+//	Musepack Demuxer
+//
+//	Author : Igor Janos
+//
+//-----------------------------------------------------------------------------
+#pragma once
+
+class CMPCReader;
+
+
+//-----------------------------------------------------------------------------
+//
+//	CMPCFile class
+//
+//-----------------------------------------------------------------------------
+
+class CMPCFile
+{
+public:
+
+	// stream header
+	__int64			duration_10mhz;			// total file duration
+	int				stream_version;			// 7, 8 are supported
+	int				sample_rate;
+	int				channels;
+	int				audio_block_frames;
+
+	// replay gain
+	float			gain_title_db;
+	float			gain_title_peak_db;
+	float			gain_album_db;
+	float			gain_album_peak_db;
+
+	// internals
+	CMPCReader		*reader;				// file reader interface
+
+	// packet parsing
+	int				key;					// key for current packet
+	uint8			*packet;				// packet payload
+	int				packet_max_size;		// maximum allowed packet size
+	int				packet_size;			// size of currently loaded payload
+	
+public:
+	CMPCFile();
+	virtual ~CMPCFile();
+
+	// I/O for MPC file
+	int Open(CMPCReader *reader);
+	int ReadNextPacket();
+
+	// parsing packets
+	int ReadStreamHeader();
+	int ReadReplaygain();
+
+};
Index: /dsfilters/demux_mpc/src/mpc_filter.cpp
===================================================================
--- /dsfilters/demux_mpc/src/mpc_filter.cpp	(revision 366)
+++ /dsfilters/demux_mpc/src/mpc_filter.cpp	(revision 366)
@@ -0,0 +1,275 @@
+//-----------------------------------------------------------------------------
+//
+//	Musepack Demuxer
+//
+//	Author : Igor Janos
+//
+//-----------------------------------------------------------------------------
+#include "stdafx.h"
+
+
+void MakeNiceSpeed(__int64 bps, CString &v)
+{
+	int r=0;
+	__int64	c=bps;
+	LPCTSTR		rady[] = {
+		_T("bps"),
+		_T("kbps"),
+		_T("mbps"),
+		_T("gbps"),
+		_T("tbps")
+	};
+
+	// spocitame rad
+	while (c > 1000 && r<4) {
+		r++;
+		c = c / 1000;
+	}
+
+	c=bps;
+	for (int i=1; i<r; i++) { c = c/1000; }
+	double d=c / 1000.0;
+
+	v.Format(_T("%5.3f %s"), (float)d, rady[r]);
+}
+
+//-----------------------------------------------------------------------------
+//
+//	CMPCDemux class
+//
+//-----------------------------------------------------------------------------
+
+CUnknown *CMPCDemux::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr)
+{
+	return new CMPCDemux(pUnk, phr);
+}
+
+CMPCDemux::CMPCDemux(LPUNKNOWN pUnk, HRESULT *phr) :
+	CBaseFilter(_T("MPC Splitter"), pUnk, &lock_filter, CLSID_MusepackDemuxer, phr),
+	reader(NULL),
+	file(NULL),
+	wnd_prop(NULL)
+{
+	input = new CMPCInputPin(NAME("MPC Input Pin"), this, phr, L"In");
+	output.RemoveAll();
+	retired.RemoveAll();
+}
+
+CMPCDemux::~CMPCDemux()
+{
+	// just to be sure
+	if (reader) { delete reader; reader = NULL; }
+	for (int i=0; i<output.GetCount(); i++) {
+		CMPCOutputPin	*pin = output[i];
+		if (pin) delete pin;
+	}
+	output.RemoveAll();
+	for (int i=0; i<retired.GetCount(); i++) {
+		CMPCOutputPin	*pin = retired[i];
+		if (pin) delete pin;
+	}
+	retired.RemoveAll();
+	if (input) { delete input; input = NULL; }
+}
+
+STDMETHODIMP CMPCDemux::NonDelegatingQueryInterface(REFIID riid,void **ppv)
+{
+    CheckPointer(ppv,E_POINTER);
+
+	if (riid == IID_ISpecifyPropertyPages) {
+		return GetInterface((ISpecifyPropertyPages*)this, ppv);
+	} else
+	if (riid == IID_IMusepackSplitter) {
+		return GetInterface((IMusepackSplitter*)this, ppv);
+	} else{
+	/*
+    if (riid == IID_IMediaSeeking) {
+        return GetInterface((IMediaSeeking *)this, ppv);
+    } else 
+	*/
+
+		return CBaseFilter::NonDelegatingQueryInterface(riid,ppv);
+	}
+}
+
+STDMETHODIMP CMPCDemux::SetPropertyPageWindow(HWND wnd)
+{
+	CAutoLock	lck(&lock_filter);
+	wnd_prop = wnd;
+	return NOERROR;
+}
+
+STDMETHODIMP CMPCDemux::GetPages(CAUUID *pPages)
+{
+    CheckPointer(pPages,E_POINTER);
+
+    pPages->cElems = 1;
+    pPages->pElems = (GUID *) CoTaskMemAlloc(sizeof(GUID));
+    if (pPages->pElems == NULL) {
+        return E_OUTOFMEMORY;
+    }
+
+	*(pPages->pElems) = CLSID_MusepackDemuxPage;
+    return NOERROR;
+
+} // GetPages
+
+int CMPCDemux::GetPinCount()
+{
+	// return pin count
+	CAutoLock	Lock(&lock_filter);
+	return ((input ? 1 : 0) + output.GetCount());
+}
+
+CBasePin *CMPCDemux::GetPin(int n)
+{
+	CAutoLock	Lock(&lock_filter);
+	if (n == 0) return input;
+	n -= 1;
+	int l = output.GetCount();
+
+	// return the requested output pin
+	if (n >= l) return NULL;
+	return output[n];
+}
+
+HRESULT CMPCDemux::CheckConnect(PIN_DIRECTION Dir, IPin *pPin)
+{
+	return NOERROR;
+}
+
+HRESULT CMPCDemux::CheckInputType(const CMediaType* mtIn)
+{
+	if (mtIn->majortype == MEDIATYPE_Stream) {
+
+		// we are sure we can accept this type
+		if (mtIn->subtype == MEDIASUBTYPE_MusepackStream) return NOERROR;
+
+		// and we may accept unknown type as well
+		if (mtIn->subtype == MEDIASUBTYPE_None ||
+			mtIn->subtype == MEDIASUBTYPE_NULL ||
+			mtIn->subtype == GUID_NULL
+			) return NOERROR;
+	} else
+	if (mtIn->majortype == GUID_NULL) {
+		return NOERROR;
+	}
+
+	// sorry.. nothing else
+	return E_FAIL;
+}
+
+HRESULT CMPCDemux::CompleteConnect(PIN_DIRECTION Dir, CBasePin *pCaller, IPin *pReceivePin)
+{
+	if (Dir == PINDIR_INPUT) {
+		// when our input pin gets connected we have to scan
+		// the input file if it is really musepack.
+		ASSERT(input && input->Reader());
+		ASSERT(!reader);
+		ASSERT(!file);
+
+		//---------------------------------------------------------------------
+		//
+		//	Analyse the source file
+		//
+		//---------------------------------------------------------------------
+		reader = new CMPCReader(input->Reader());
+		file = new CMPCFile();
+
+		// try to open the file
+		int ret = file->Open(reader);
+		if (ret < 0) {
+			delete file;	file = NULL;
+			delete reader;	reader = NULL;
+			return E_FAIL;
+		}
+
+		// refresh property page if there is any
+		if (IsWindow(wnd_prop)) {
+			PostMessage(wnd_prop, WM_UPDATE_VISUALS, 0, 0);
+		}
+
+	} else {
+	}
+	return NOERROR;
+}
+
+
+HRESULT CMPCDemux::RemoveOutputPins()
+{
+	CAutoLock	Lck(&lock_filter);
+	if (m_State != State_Stopped) return VFW_E_NOT_STOPPED;
+
+	// we retire all current output pins
+	for (int i=0; i<output.GetCount(); i++) {
+		CMPCOutputPin *pin = output[i];
+		if (pin->IsConnected()) {
+			pin->GetConnected()->Disconnect();
+			pin->Disconnect();
+		}
+		retired.Add(pin);
+	}
+	output.RemoveAll();
+	return NOERROR;
+}
+
+
+HRESULT CMPCDemux::BreakConnect(PIN_DIRECTION Dir, CBasePin *pCaller)
+{
+	ASSERT(m_State == State_Stopped);
+
+	if (Dir == PINDIR_INPUT) {
+		// let's disconnect the output pins
+		//ev_abort.Set();
+		//ev_ready.Set();
+
+		HRESULT hr = RemoveOutputPins();
+		if (FAILED(hr)) return hr;
+
+		// destroy input file
+		if (file) { delete file; file = NULL; }
+
+		// destroy reader
+		if (reader) { delete reader; reader = NULL;	}
+
+		// refresh property page if there is any
+		if (IsWindow(wnd_prop)) {
+			PostMessage(wnd_prop, WM_UPDATE_VISUALS, 0, 0);
+		}
+
+		//ev_abort.Reset();
+	} else 
+	if (Dir == PINDIR_OUTPUT) {
+		// nothing yet
+	}
+	return NOERROR;
+}
+
+
+// Output pins
+HRESULT CMPCDemux::AddOutputPin(CMPCOutputPin *pPin)
+{
+	CAutoLock	lck(&lock_filter);
+	output.Add(pPin);
+	return NOERROR;
+}
+
+STDMETHODIMP CMPCDemux::GetFileInfo(MPC_File_Info *info)
+{
+	CAutoLock	lck(&lock_filter);
+	if (!info) return E_POINTER;
+	if (!file) return E_FAIL;
+	
+	// fill in the struct
+	info->duration = file->duration_10mhz / 10000000.0;
+	info->stream_version = file->stream_version;
+	info->channels = file->channels;
+	info->sample_rate = file->sample_rate;
+	info->block_frames = file->audio_block_frames;
+
+	return NOERROR;
+}
+
+
+
+
Index: /dsfilters/demux_mpc/src/mpc_filter.h
===================================================================
--- /dsfilters/demux_mpc/src/mpc_filter.h	(revision 366)
+++ /dsfilters/demux_mpc/src/mpc_filter.h	(revision 366)
@@ -0,0 +1,95 @@
+//-----------------------------------------------------------------------------
+//
+//	Musepack Demuxer
+//
+//	Author : Igor Janos
+//
+//-----------------------------------------------------------------------------
+#pragma once
+
+#define CMD_EXIT		0
+#define CMD_STOP		1
+#define CMD_RUN			2
+
+
+//-----------------------------------------------------------------------------
+//
+//	CMPCDemux class
+//
+//-----------------------------------------------------------------------------
+class CMPCDemux : 
+	public CBaseFilter,
+	public ISpecifyPropertyPages ,
+	public IMusepackSplitter
+{
+public:
+
+	CCritSec					lock_filter;
+	CMPCInputPin				*input;
+	CArray<CMPCOutputPin*>		output;
+	CArray<CMPCOutputPin*>		retired;
+	CMPCReader					*reader;
+	CMPCFile					*file;
+	HWND						wnd_prop;
+
+public:
+	// constructor
+	CMPCDemux(LPUNKNOWN pUnk, HRESULT *phr);
+	virtual ~CMPCDemux();
+	static CUnknown * WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *phr);
+
+	// override this to publicise our interfaces
+	DECLARE_IUNKNOWN;
+	STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
+
+    // ISpecifyPropertyPages interface
+    STDMETHODIMP GetPages(CAUUID *pPages);
+
+	// CBaseFilter
+	virtual int GetPinCount();
+    virtual CBasePin *GetPin(int n);
+
+	// Output pins
+	HRESULT AddOutputPin(CMPCOutputPin *pPin);
+	virtual HRESULT RemoveOutputPins();
+	CMPCOutputPin *FindStream(int stream_no);
+
+    // check that we can support this input type
+    virtual HRESULT CheckInputType(const CMediaType* mtIn);
+	virtual HRESULT CheckConnect(PIN_DIRECTION Dir, IPin *pPin);
+	virtual HRESULT BreakConnect(PIN_DIRECTION Dir, CBasePin *pCaller);
+	virtual HRESULT CompleteConnect(PIN_DIRECTION Dir, CBasePin *pCaller, IPin *pReceivePin);
+
+
+	// IMusepackSplitter
+	STDMETHODIMP GetFileInfo(MPC_File_Info *info);
+	STDMETHODIMP SetPropertyPageWindow(HWND wnd);
+
+
+	// IMediaSeeking
+	/*
+	STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
+	STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
+	STDMETHODIMP IsFormatSupported(const GUID* pFormat);
+	STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
+	STDMETHODIMP GetTimeFormat(GUID* pFormat);
+	STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
+	STDMETHODIMP SetTimeFormat(const GUID* pFormat);
+	STDMETHODIMP GetDuration(LONGLONG* pDuration);
+	STDMETHODIMP GetStopPosition(LONGLONG* pStop);
+	STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
+	STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
+	STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
+	STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
+	STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
+	STDMETHODIMP SetRate(double dRate);
+	STDMETHODIMP GetRate(double* pdRate);
+	STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
+	STDMETHODIMP SetPositionsInternal(int iD, LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
+
+	// virtual HRESULT DoNewSeek();
+	*/
+
+};
+
+
Index: /dsfilters/demux_mpc/src/mpc_pin.cpp
===================================================================
--- /dsfilters/demux_mpc/src/mpc_pin.cpp	(revision 366)
+++ /dsfilters/demux_mpc/src/mpc_pin.cpp	(revision 366)
@@ -0,0 +1,747 @@
+//-----------------------------------------------------------------------------
+//
+//	Musepack Demuxer
+//
+//	Author : Igor Janos
+//
+//-----------------------------------------------------------------------------
+#include "stdafx.h"
+
+
+//-----------------------------------------------------------------------------
+//
+//	CMPCInputPin class
+//
+//-----------------------------------------------------------------------------
+
+CMPCInputPin::CMPCInputPin(TCHAR *pObjectName, CMPCDemux *pDemux, HRESULT *phr, LPCWSTR pName) :
+	CBaseInputPin(pObjectName, pDemux, &pDemux->lock_filter, phr, pName),
+	reader(NULL)
+{
+	// assign the splitter filter
+	demux = pDemux;
+}
+
+CMPCInputPin::~CMPCInputPin()
+{
+	if (reader) { reader->Release(); reader = NULL; }
+}
+
+// this is a pull mode pin - these can not happen
+
+STDMETHODIMP CMPCInputPin::EndOfStream()		{ return E_UNEXPECTED; }
+STDMETHODIMP CMPCInputPin::BeginFlush()			{ return E_UNEXPECTED; }
+STDMETHODIMP CMPCInputPin::EndFlush()			{ return E_UNEXPECTED; }
+STDMETHODIMP CMPCInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double rate)	{ return E_UNEXPECTED; }
+
+// we don't support this kind of transport
+STDMETHODIMP CMPCInputPin::Receive(IMediaSample * pSample) { return E_UNEXPECTED; }
+
+// check for input type
+HRESULT CMPCInputPin::CheckConnect(IPin *pPin)
+{
+	HRESULT hr = demux->CheckConnect(PINDIR_INPUT, pPin);
+	if (FAILED(hr)) return hr;
+
+	return CBaseInputPin::CheckConnect(pPin);
+}
+
+HRESULT CMPCInputPin::BreakConnect()
+{
+	// Can't disconnect unless stopped
+	ASSERT(IsStopped());
+
+	demux->BreakConnect(PINDIR_INPUT, this);
+
+	// release the reader
+	if (reader) reader->Release(); reader = NULL;
+	return CBaseInputPin::BreakConnect();
+}
+
+HRESULT CMPCInputPin::CompleteConnect(IPin *pReceivePin)
+{
+	// make sure there is a pin
+	ASSERT(pReceivePin);
+
+	if (reader) reader->Release(); reader = NULL;
+
+	// and make sure it supports IAsyncReader
+	HRESULT hr = pReceivePin->QueryInterface(IID_IAsyncReader, (void **)&reader);
+	if (FAILED(hr)) return hr;
+
+	// we're done here
+	hr = demux->CompleteConnect(PINDIR_INPUT, this, pReceivePin);
+	if (FAILED(hr)) return hr;
+
+	return CBaseInputPin::CompleteConnect(pReceivePin);
+}
+
+HRESULT CMPCInputPin::CheckMediaType(const CMediaType* pmt)
+{
+	// make sure we have a type
+	ASSERT(pmt);
+
+	// ask the splitter
+	return demux->CheckInputType(pmt);
+}
+
+HRESULT CMPCInputPin::SetMediaType(const CMediaType* pmt)
+{
+	// let the baseclass know
+	if (FAILED(CheckMediaType(pmt))) return E_FAIL;
+
+	HRESULT hr = CBasePin::SetMediaType(pmt);
+	if (FAILED(hr)) return hr;
+
+	return NOERROR;
+}
+
+HRESULT CMPCInputPin::Inactive()
+{
+	HRESULT hr = CBaseInputPin::Inactive();
+	if (hr == VFW_E_NO_ALLOCATOR) hr = NOERROR;
+	if (FAILED(hr)) return hr;
+
+	return hr;
+}
+
+//-----------------------------------------------------------------------------
+//
+//	CMPCOutputPin class
+//
+//-----------------------------------------------------------------------------
+
+CMPCOutputPin::CMPCOutputPin(TCHAR *pObjectName, CMPCDemux *pDemux, HRESULT *phr, LPCWSTR pName, int iBuffers) :
+	CBaseOutputPin(pObjectName, pDemux, &pDemux->lock_filter, phr, pName),
+	CAMThread(),
+	demux(pDemux),
+	buffers(iBuffers),
+	active(false),
+	rtStart(0),
+	rtStop(0xffffffffffff),
+	rate(1.0),
+	ev_can_read(TRUE),
+	ev_can_write(TRUE),
+	ev_abort(TRUE)
+{
+	discontinuity = true;
+	eos_delivered = false;
+
+	ev_can_read.Reset();
+	ev_can_write.Set();
+	ev_abort.Reset();
+}
+
+CMPCOutputPin::~CMPCOutputPin()
+{
+	// nothing yet
+}
+
+STDMETHODIMP CMPCOutputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
+{
+	CheckPointer(ppv, E_POINTER);
+	/*
+	if (riid == IID_IMediaSeeking) {
+		return GetInterface((IMediaSeeking*)this, ppv);
+	} else {
+	*/
+		return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv);
+	//}
+}
+
+HRESULT CMPCOutputPin::CheckMediaType(const CMediaType *mtOut)
+{
+	for (int i=0; i<mt_types.GetCount(); i++) {
+		if (mt_types[i] == *mtOut) return NOERROR;
+	}
+
+	// reject type if it's not among ours
+	return E_FAIL;
+}
+
+HRESULT CMPCOutputPin::SetMediaType(const CMediaType *pmt)
+{
+	// just set internal media type
+	if (FAILED(CheckMediaType(pmt))) return E_FAIL;
+	return CBaseOutputPin::SetMediaType(pmt);
+}
+
+HRESULT CMPCOutputPin::GetMediaType(int iPosition, CMediaType *pmt)
+{
+	// enumerate the list
+	if (iPosition < 0) return E_INVALIDARG;
+	if (iPosition >= mt_types.GetCount()) return VFW_S_NO_MORE_ITEMS;
+
+	*pmt = mt_types[iPosition];
+	return NOERROR;
+}
+
+HRESULT CMPCOutputPin::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProp)
+{
+	ASSERT(pAlloc);
+	ASSERT(pProp);
+	HRESULT hr = NOERROR;
+
+	pProp->cBuffers = max(buffers, 1);
+	pProp->cbBuffer = max(m_mt.lSampleSize, 1);
+	ALLOCATOR_PROPERTIES	Actual;
+	hr = pAlloc->SetProperties(pProp, &Actual);
+	if (FAILED(hr)) return hr;
+
+	ASSERT(Actual.cBuffers >= pProp->cBuffers);
+	return NOERROR;
+}
+
+HRESULT CMPCOutputPin::BreakConnect()
+{
+	ASSERT(IsStopped());
+	demux->BreakConnect(PINDIR_OUTPUT, this);
+	discontinuity = true;
+	return CBaseOutputPin::BreakConnect();
+}
+
+HRESULT CMPCOutputPin::CompleteConnect(IPin *pReceivePin)
+{
+	// let the parent know
+	HRESULT hr = demux->CompleteConnect(PINDIR_OUTPUT, this, pReceivePin);
+	if (FAILED(hr)) return hr;
+
+	discontinuity = true;
+	// okey
+	return CBaseOutputPin::CompleteConnect(pReceivePin);
+}
+
+STDMETHODIMP CMPCOutputPin::Notify(IBaseFilter *pSender, Quality q)
+{
+	return S_FALSE;
+}
+
+HRESULT CMPCOutputPin::Inactive()
+{
+	if (!active) return NOERROR;
+	active = FALSE;
+
+	// destroy everything
+	ev_abort.Set();
+	HRESULT hr = CBaseOutputPin::Inactive();
+	ASSERT(SUCCEEDED(hr));
+
+	if (ThreadExists()) {
+		CallWorker(CMD_EXIT);
+		Close();
+	}
+	FlushQueue();
+	ev_abort.Reset();
+
+	return NOERROR;
+}
+
+
+HRESULT CMPCOutputPin::Active()
+{
+	if (active) return NOERROR;
+	
+	FlushQueue();
+	if (!IsConnected()) return VFW_E_NOT_CONNECTED;
+
+	ev_abort.Reset();
+
+	// vytvorime novu queue
+	if (!ThreadExists()) {
+		Create();
+		CallWorker(CMD_RUN);
+	}
+
+	HRESULT hr = CBaseOutputPin::Active();
+	if (FAILED(hr)) {
+		active = FALSE;
+		return hr;
+	}
+
+	// new segment
+	DoNewSegment(rtStart, rtStop, rate);
+	active = TRUE;
+	return hr;
+}
+
+
+HRESULT CMPCOutputPin::DoNewSegment(REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double dRate)
+{
+	DataPacket	*packet;
+	int ret = GetDataPacket(&packet);
+	if (ret < 0 || !packet) return E_FAIL;
+
+	// queue the EOS packet
+	this->rtStart = rtStart;
+	this->rtStop = rtStop;
+	this->rate = dRate;
+	eos_delivered = false;
+
+	{
+		CAutoLock	lck(&lock_queue);
+		packet->type = DataPacket::PACKET_TYPE_NEW_SEGMENT;
+		packet->rtStart = rtStart;
+		packet->rtStop = rtStop;
+		packet->rate = rate;
+		queue.AddTail(packet);
+		ev_can_read.Set();
+		discontinuity = true;
+	}
+
+	return NOERROR;
+}
+
+/*
+// IMediaSeeking
+STDMETHODIMP CMPCOutputPin::GetCapabilities(DWORD* pCapabilities)					{ return demux->GetCapabilities(pCapabilities); }
+STDMETHODIMP CMPCOutputPin::CheckCapabilities(DWORD* pCapabilities)					{ return demux->CheckCapabilities(pCapabilities); }
+STDMETHODIMP CMPCOutputPin::IsFormatSupported(const GUID* pFormat)					{ return demux->IsFormatSupported(pFormat); }
+STDMETHODIMP CMPCOutputPin::QueryPreferredFormat(GUID* pFormat)						{ return demux->QueryPreferredFormat(pFormat); }
+STDMETHODIMP CMPCOutputPin::GetTimeFormat(GUID* pFormat)							{ return demux->GetTimeFormat(pFormat); }
+STDMETHODIMP CMPCOutputPin::IsUsingTimeFormat(const GUID* pFormat)					{ return demux->IsUsingTimeFormat(pFormat); }
+STDMETHODIMP CMPCOutputPin::SetTimeFormat(const GUID* pFormat)						{ return demux->SetTimeFormat(pFormat); }
+STDMETHODIMP CMPCOutputPin::GetDuration(LONGLONG* pDuration)						{ return demux->GetDuration(pDuration); }
+STDMETHODIMP CMPCOutputPin::GetStopPosition(LONGLONG* pStop)						{ return demux->GetStopPosition(pStop); }
+STDMETHODIMP CMPCOutputPin::GetCurrentPosition(LONGLONG* pCurrent)					{ return demux->GetCurrentPosition(pCurrent); }
+STDMETHODIMP CMPCOutputPin::GetPositions(LONGLONG* pCurrent, LONGLONG* pStop)		{ return demux->GetPositions(pCurrent, pStop); }
+STDMETHODIMP CMPCOutputPin::GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest)	{ return demux->GetAvailable(pEarliest, pLatest); }
+STDMETHODIMP CMPCOutputPin::SetRate(double dRate)									{ return demux->SetRate(dRate); }
+STDMETHODIMP CMPCOutputPin::GetRate(double* pdRate)									{ return demux->GetRate(pdRate); }
+STDMETHODIMP CMPCOutputPin::GetPreroll(LONGLONG* pllPreroll)						{ return demux->GetPreroll(pllPreroll); }
+STDMETHODIMP CMPCOutputPin::ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat)
+{
+	return demux->ConvertTimeFormat(pTarget, pTargetFormat, Source, pSourceFormat);
+}
+STDMETHODIMP CMPCOutputPin::SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags)
+{
+	return demux->SetPositionsInternal(stream_index, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
+}
+*/
+
+int CMPCOutputPin::GetDataPacket(DataPacket **packet)
+{
+	// this method may blokc
+	HANDLE	events[] = { ev_can_write, ev_abort };
+	DWORD	ret;
+
+	do {
+		// if the abort event is set, quit
+		if (ev_abort.Check()) return -1;
+
+		ret = WaitForMultipleObjects(2, events, FALSE, 10);
+		if (ret == WAIT_OBJECT_0) {
+			// return new packet
+			*packet = new DataPacket();
+			return 0;
+		}
+
+	} while (1);
+
+	// unexpected
+	return -1;
+}
+
+/*
+// dorucenie packetu
+HRESULT CMPCOutputPin::DeliverPacket(MP4::Packet &packet)
+{
+	// ziskame novy packet na vystup
+	DataPacket	*outp = NULL;
+	int ret = GetDataPacket(&outp);
+	if (ret < 0 || !outp) return E_FAIL;
+
+	REFERENCE_TIME start, stop;
+
+	outp->type	  = DataPacket::PACKET_TYPE_DATA;
+
+	// spocitame casy
+	outp->rtStart = (packet.pts_100mhz / 10) - rtStart;
+	outp->rtStop  = outp->rtStart + 1;
+	
+	outp->size	  = packet.size;
+	outp->buf	  = (BYTE*)malloc(outp->size);
+	memcpy(outp->buf, packet.data, packet.size);
+
+	// sync point ?
+	if (packet.flags & PACKET_FLAG_KEYFRAME) {
+		outp->sync_point = TRUE;
+	} else {
+		outp->sync_point = FALSE;
+	}
+
+	// discontinuity ?
+	if (discontinuity) {
+		outp->discontinuity = TRUE;
+		discontinuity = false;
+	} else {
+		outp->discontinuity = FALSE;
+	}
+
+	{
+		// strcime do queue
+		MonoBase::AutoLock		lck(&lock_queue);
+		queue.AddTail(outp);
+		ev_can_read.Set();
+
+		// zakazeme dalsie bufferovanie
+		// toto mozeme robit iba pre seekovaci pin
+		if (stream_index == demux->buf_index) {
+			if (GetBufferTime_MS() >= buffer_time_ms) {
+				ev_can_write.Reset();
+			}
+		}
+	}
+
+	return NOERROR;
+}
+*/
+
+HRESULT CMPCOutputPin::DoEndOfStream()
+{
+	DataPacket	*packet;
+	int ret = GetDataPacket(&packet);
+	if (ret < 0 || !packet) return E_FAIL;
+
+	// naqueueujeme EOS
+	{
+		CAutoLock	lck(&lock_queue);
+		packet->type = DataPacket::PACKET_TYPE_EOS;
+		queue.AddTail(packet);
+		ev_can_read.Set();
+	}
+	eos_delivered = true;
+
+	return NOERROR;
+}
+
+void CMPCOutputPin::FlushQueue()
+{
+	CAutoLock	lck(&lock_queue);
+	while (queue.GetCount() > 0) {
+		DataPacket *packet = queue.RemoveHead();
+		if (packet) delete packet;
+	}
+	ev_can_read.Reset();
+	ev_can_write.Set();
+
+	// we return buffer level only for the first pin
+	/*
+	if (stream_index == demux->buf_index) {
+		//MonoBase::AutoLock	lck2(&demux->lock_info);
+		demux->buf_size_ms = GetBufferTime_MS();
+	}
+	*/
+}
+
+HRESULT CMPCOutputPin::DeliverDataPacket(DataPacket &packet)
+{
+	IMediaSample	*sample;
+	HRESULT hr = GetDeliveryBuffer(&sample, NULL, NULL, 0);
+	if (FAILED(hr)) return E_FAIL;
+
+	// we should have enough space in there
+	ASSERT(sample->GetSize() >= packet.size);
+
+	BYTE			*buf;
+	sample->GetPointer(&buf);
+
+	//*************************************************************************
+	//
+	//	data
+	//
+	//*************************************************************************
+
+	memcpy(buf, packet.buf, packet.size);
+	sample->SetActualDataLength(packet.size);
+
+	// sync point, discontinuity ?
+	if (packet.sync_point)		{ sample->SetSyncPoint(TRUE);     } else { sample->SetSyncPoint(FALSE);     }
+	if (packet.discontinuity)	{ sample->SetDiscontinuity(TRUE); } else { sample->SetDiscontinuity(FALSE); }
+
+	// do we have a time stamp ?
+	if (packet.has_time)		{ sample->SetTime(&packet.rtStart, &packet.rtStop); }
+
+	// dorucime
+	hr = Deliver(sample);	
+	sample->Release();
+	return hr;
+}
+
+__int64 CMPCOutputPin::GetBufferTime_MS()
+{
+	CAutoLock	lck(&lock_queue);
+	if (queue.IsEmpty()) return 0;
+
+	DataPacket	*pfirst;
+	DataPacket	*plast;
+	__int64		tstart, tstop;
+	POSITION	posf, posl;
+
+	tstart = -1;
+	tstop = -1;
+
+	posf = queue.GetHeadPosition();
+	while (posf) {
+		pfirst = queue.GetNext(posf);
+		if (pfirst->type == DataPacket::PACKET_TYPE_DATA && pfirst->rtStart != -1) {
+			tstart = pfirst->rtStart;
+			break;
+		}
+	}
+
+	posl = queue.GetTailPosition();
+	while (posl) {
+		plast = queue.GetPrev(posl);
+		if (plast->type == DataPacket::PACKET_TYPE_DATA && plast->rtStart != -1) {
+			tstop = plast->rtStart;
+			break;
+		}
+	}
+
+	if (tstart == -1 || tstop == -1) return 0;
+
+	// calculate time in milliseconds
+	return (tstop - tstart) / 10000;
+}
+
+// vlakno na output
+DWORD CMPCOutputPin::ThreadProc()
+{
+	while (true) {
+		DWORD cmd = GetRequest();
+		switch (cmd) {
+		case CMD_EXIT:		Reply(0); return 0; break;
+		case CMD_STOP:		Reply(0); break;
+		case CMD_RUN:
+			{
+				Reply(0);
+				if (!IsConnected()) break;
+
+				// deliver packets
+				DWORD		cmd2;
+				BOOL		is_first = true;
+				DataPacket	*packet;
+				HRESULT		hr;
+
+				do {
+					if (ev_abort.Check()) break;
+					hr = NOERROR;
+					
+					HANDLE	events[] = { ev_can_read, ev_abort};
+					DWORD	ret = WaitForMultipleObjects(2, events, FALSE, 10);
+
+					if (ret == WAIT_OBJECT_0) {
+						// look for new packet in queue
+						{
+							CAutoLock	lck(&lock_queue);
+							packet = queue.RemoveHead();
+							if (queue.IsEmpty()) ev_can_read.Reset();
+
+							// allow buffering
+							if (GetBufferTime_MS() < buffer_time_ms) ev_can_write.Set();
+						}
+
+						// bud dorucime End Of Stream, alebo packet
+						if (packet->type == DataPacket::PACKET_TYPE_EOS) {
+							DeliverEndOfStream();
+						} else 
+						if (packet->type == DataPacket::PACKET_TYPE_DATA) {
+							hr = DeliverDataPacket(*packet);
+							if (SUCCEEDED(hr)) {
+
+								/*
+								if (stream_index == demux->buf_index) {
+									int	size = GetBufferTime_MS();
+									{
+										MonoBase::AutoLock	lck2(&demux->lock_info);
+										demux->buf_size_ms = size;
+										demux->NotifyEvent(EC_BUFFER_STATE, size, demux->internal_buffer_size);		// v milisekundach
+									}
+									demux->UpdatePage(1);
+
+									// posleme notifikaciu, ze data boli dorucene
+									if (is_first) {
+										is_first = false;
+										demux->NotifyEvent(EC_FRAME_READY, 0, 0);
+									}
+
+									// starvation
+									if (size < 0.05*demux->internal_buffer_size && !eos_delivered &&
+										demux->ev_ready.Check() == TRUE
+										) {
+										demux->NotifyStarvation();
+									}
+								}
+								*/
+							}
+						}					
+
+						delete packet;
+
+						if (FAILED(hr)) {
+							break;
+						}
+					}
+				} while (!CheckRequest(&cmd2));
+			}
+			break;
+		default:
+			Reply(E_UNEXPECTED); 
+			break;
+		}
+	}
+	return 0;
+}
+
+
+//-----------------------------------------------------------------------------
+//
+//	CMPCReader class
+//
+//-----------------------------------------------------------------------------
+CMPCReader::CMPCReader(IAsyncReader *rd)
+{
+	ASSERT(rd);
+
+	reader = rd;
+	reader->AddRef();
+	pos = 0;
+}
+
+CMPCReader::~CMPCReader()
+{
+	if (reader) {
+		reader->Release();
+		reader = NULL;
+	}
+}
+
+int CMPCReader::GetSize(__int64 *avail, __int64 *total)
+{
+	// vraciame velkost
+	HRESULT hr = reader->Length(total, avail);
+	if (FAILED(hr)) return -1;
+	return 0;
+}
+
+int CMPCReader::GetPosition(__int64 *pos, __int64 *avail)
+{
+	HRESULT hr;
+	__int64	total;
+	hr = reader->Length(&total, avail);
+	if (FAILED(hr)) return -1;
+
+	// aktualna pozicia
+	if (pos) *pos = this->pos;
+	return 0;
+}
+
+int CMPCReader::Seek(__int64 pos)
+{
+	__int64	avail, total;
+	GetSize(&avail, &total);
+	if (pos < 0 || pos >= total) return -1;
+
+	// seekneme
+	this->pos = pos;
+	return 0;
+}
+
+int CMPCReader::Read(void *buf, int size)
+{
+	__int64	avail, total;
+	GetSize(&avail, &total);
+	if (pos + size > avail) return -1;
+
+	// TODO: Caching here !!!!
+
+	HRESULT hr = reader->SyncRead(pos, size, (BYTE*)buf);
+	if (FAILED(hr)) return -2;
+
+	// update position
+	pos += size;
+	return 0;
+}
+
+// reading syntax elements
+int CMPCReader::GetMagick(uint32 &elm)
+{
+	uint8	buf[4];
+	int ret = Read(buf, sizeof(buf));
+	if (ret < 0) return ret;
+
+	// network byte order
+	elm = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]);
+	return 0;
+}
+
+int CMPCReader::GetKey(uint16 &key)
+{
+	uint8	buf[2];
+	int ret = Read(buf, sizeof(buf));
+	if (ret < 0) return ret;
+
+	// network byte order
+	key = (buf[0] << 8) | (buf[1]);
+	return 0;
+}
+
+int CMPCReader::GetSizeElm(int64 &size, int32 &size_len)
+{
+	int	ret;
+	size = 0;
+	size_len = 1;
+
+	while (true) {
+		uint8	val;
+		ret = Read(&val, 1); if (ret < 0) return ret;
+
+		// this is the last one
+		if (!(val&0x80)) { size |= val&0x7f; return 0; }
+
+		// not the last one
+		size |= (val&0x7f);
+		size <<= 7;
+		size_len ++;
+	}
+	return 0;	
+}
+
+bool CMPCReader::KeyValid(uint16 key)
+{
+	// according to the specs keys can only take specific values.
+	if (((key>>8)&0xff) < 65 || ((key>>8)&0xff) > 90) return false;
+	if ((key&0xff) < 65 || (key&0xff) > 90) return false;
+	return true;
+}
+
+
+DataPacket::DataPacket() :
+	type(PACKET_TYPE_EOS),
+	rtStart(0),
+	rtStop(0),
+	sync_point(FALSE),
+	discontinuity(FALSE),
+	buf(NULL),
+	size(0)
+{
+}
+
+DataPacket::~DataPacket()
+{
+	if (buf) {
+		free(buf);
+		buf = NULL;
+	}
+}
+
+
+
+
+
+
+
+
+
+
+
Index: /dsfilters/demux_mpc/src/mpc_pin.h
===================================================================
--- /dsfilters/demux_mpc/src/mpc_pin.h	(revision 366)
+++ /dsfilters/demux_mpc/src/mpc_pin.h	(revision 366)
@@ -0,0 +1,217 @@
+//-----------------------------------------------------------------------------
+//
+//	Musepack Demuxer
+//
+//	Author : Igor Janos
+//
+//-----------------------------------------------------------------------------
+#pragma once
+
+
+class CMPCDemux;
+
+
+//-----------------------------------------------------------------------------
+//
+//	CMPCInputPin class
+//
+//-----------------------------------------------------------------------------
+class CMPCInputPin : public CBaseInputPin
+{
+public:
+
+	// parent splitter
+	CMPCDemux		*demux;
+	IAsyncReader	*reader;
+
+public:
+	CMPCInputPin(TCHAR *pObjectName, CMPCDemux *pDemux, HRESULT *phr, LPCWSTR pName);
+	virtual ~CMPCInputPin();
+
+	// Get hold of IAsyncReader interface
+	HRESULT CompleteConnect(IPin *pReceivePin);
+	HRESULT CheckConnect(IPin *pPin);
+	HRESULT BreakConnect();
+	HRESULT CheckMediaType(const CMediaType *pmt);
+	HRESULT SetMediaType(const CMediaType *pmt);
+
+	// IMemInputPIn
+	STDMETHODIMP Receive(IMediaSample *pSample);
+	STDMETHODIMP EndOfStream(void);
+	STDMETHODIMP BeginFlush();
+	STDMETHODIMP EndFlush();
+	STDMETHODIMP NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double rate);
+
+	HRESULT Inactive();	
+public:
+	// Helpers
+	CMediaType &CurrentMediaType() { return m_mt; }
+	IAsyncReader *Reader() { return reader; }
+};
+
+//-----------------------------------------------------------------------------
+//
+//	DataPacket class
+//
+//-----------------------------------------------------------------------------
+class DataPacket
+{
+public:
+	int		type;
+
+	enum {
+		PACKET_TYPE_EOS	= 0,
+		PACKET_TYPE_DATA = 1,
+		PACKET_TYPE_NEW_SEGMENT = 2
+	};
+
+	REFERENCE_TIME	rtStart, rtStop;
+	double			rate;
+	bool			has_time;
+	BOOL			sync_point;
+	BOOL			discontinuity;
+	BYTE			*buf;
+	int				size;
+
+public:
+	DataPacket();
+	virtual ~DataPacket();
+
+};
+
+typedef CArray<CMediaType> CMediaTypes;
+
+//-----------------------------------------------------------------------------
+//
+//	CMPCOutputPin class
+//
+//-----------------------------------------------------------------------------
+class CMPCOutputPin : 
+	public CBaseOutputPin, 
+//	public IMediaSeeking, 
+	public CAMThread
+{
+public:
+
+	// parser
+	CMPCDemux			*demux;
+	int					stream_index;
+	CMediaTypes			mt_types;
+
+	// buffer queue
+	int					buffers;
+	CList<DataPacket*>	queue;
+	CCritSec			lock_queue;
+	CAMEvent			ev_can_read;
+	CAMEvent			ev_can_write;
+	CAMEvent			ev_abort;
+	int					buffer_time_ms;
+
+	// time stamps
+	REFERENCE_TIME		rtStart;
+	REFERENCE_TIME		rtStop;
+	double				rate;
+	bool				active;
+	bool				discontinuity;
+	bool				eos_delivered;
+
+public:
+	CMPCOutputPin(TCHAR *pObjectName, CMPCDemux *pDemux, HRESULT *phr, LPCWSTR pName, int iBuffers);
+	virtual ~CMPCOutputPin();
+
+	// IUNKNOWN
+	DECLARE_IUNKNOWN;
+	STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
+
+	// MediaType stuff
+	HRESULT CheckMediaType(const CMediaType *pmt);
+	HRESULT SetMediaType(const CMediaType *pmt);
+	HRESULT GetMediaType(int iPosition, CMediaType *pmt);
+	HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProp);
+	HRESULT BreakConnect();
+	HRESULT CompleteConnect(IPin *pReceivePin);
+
+	// Activation/Deactivation
+	HRESULT Active();
+	HRESULT Inactive();
+	HRESULT DoNewSegment(REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double dRate);
+
+	STDMETHODIMP Notify(IBaseFilter *pSender, Quality q);
+
+	// packet delivery mechanism
+	//HRESULT DeliverPacket(MP4::Packet &packet);
+	HRESULT DeliverDataPacket(DataPacket &packet);
+	HRESULT DoEndOfStream();
+
+	// delivery thread
+	virtual DWORD ThreadProc();
+	void FlushQueue();
+	int GetDataPacket(DataPacket **packet);
+
+	/*
+	// IMediaSeeking
+	STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
+	STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
+	STDMETHODIMP IsFormatSupported(const GUID* pFormat);
+	STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
+	STDMETHODIMP GetTimeFormat(GUID* pFormat);
+	STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
+	STDMETHODIMP SetTimeFormat(const GUID* pFormat);
+	STDMETHODIMP GetDuration(LONGLONG* pDuration);
+	STDMETHODIMP GetStopPosition(LONGLONG* pStop);
+	STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
+	STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
+	STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
+	STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
+	STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
+	STDMETHODIMP SetRate(double dRate);
+	STDMETHODIMP GetRate(double* pdRate);
+	STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
+	*/
+
+public:
+	CMediaType &CurrentMediaType() { return m_mt; }
+	IMemAllocator *Allocator() { return m_pAllocator; }
+	REFERENCE_TIME CurrentStart() { return rtStart; }
+	REFERENCE_TIME CurrentStop() { return rtStop; }
+	double CurrentRate() { return rate; }
+	__int64 GetBufferTime_MS();
+};
+
+//-----------------------------------------------------------------------------
+//
+//	CMPCReader class
+//
+//	Todo: caching...
+//
+//-----------------------------------------------------------------------------
+
+#define MPC_KEY(k1,k2)		((k1<<8)|(k2))
+
+class CMPCReader
+{
+protected:
+	IAsyncReader	*reader;
+	__int64			pos;
+
+public:
+	CMPCReader(IAsyncReader *rd);
+	virtual ~CMPCReader();
+
+	virtual int GetSize(__int64 *avail, __int64 *total);
+	virtual int GetPosition(__int64 *pos, __int64 *avail);
+	virtual int Seek(__int64 pos);
+	virtual int Read(void *buf, int size);
+
+	void BeginFlush() { if (reader) reader->BeginFlush(); }
+	void EndFlush() { if (reader) reader->EndFlush(); }
+
+	// reading syntax elements - in network byte order
+	int GetMagick(uint32 &elm);
+	int GetKey(uint16 &key);
+	int GetSizeElm(int64 &size, int32 &size_len);
+	bool KeyValid(uint16 key);
+
+};
+
+
Index: /dsfilters/demux_mpc/src/mpc_prop.cpp
===================================================================
--- /dsfilters/demux_mpc/src/mpc_prop.cpp	(revision 366)
+++ /dsfilters/demux_mpc/src/mpc_prop.cpp	(revision 366)
@@ -0,0 +1,160 @@
+//-----------------------------------------------------------------------------
+//
+//	Musepack Demuxer
+//
+//	Author : Igor Janos
+//
+//-----------------------------------------------------------------------------
+#include "stdafx.h"
+
+#include "..\resource.h"
+
+
+// minimalny a maximalny cas, ktory je mozne navolit v property pagese
+#define	MIN_TIME				1
+#define MAX_TIME				10
+#define ITEM(x)					GetDlgItem(m_Dlg, x)
+
+void MakeNiceTime(int time_ms, CString &v)
+{
+	int		ms = time_ms%1000;	
+	time_ms -= ms;
+	time_ms /= 1000;
+
+	int		h, m, s;
+	h = time_ms / 3600;		time_ms -= h*3600;
+	m = time_ms / 60;		time_ms -= m*60;
+	s = time_ms;
+
+	v.Format(_T("%.2d:%.2d:%.2d,%.3d"), h, m, s, ms);
+}
+
+
+//-----------------------------------------------------------------------------
+//
+//	CMPCPropertyPage class
+//
+//-----------------------------------------------------------------------------
+
+CUnknown *CMPCPropertyPage::CreateInstance(LPUNKNOWN lpUnk, HRESULT *phr)
+{
+	return new CMPCPropertyPage(lpUnk, phr);
+}
+
+CMPCPropertyPage::CMPCPropertyPage(LPUNKNOWN lpUnk, HRESULT *phr) :
+	CBasePropertyPage(NAME("MPC Property Page"), lpUnk, IDD_PAGE_DEMUX, IDS_PAGE_DEMUX),
+	demux(NULL)
+{
+}
+
+CMPCPropertyPage::~CMPCPropertyPage()
+{
+}
+
+HRESULT CMPCPropertyPage::OnConnect(IUnknown *pUnknown)
+{
+	// hold a pointer
+	ASSERT(!demux);
+
+	HRESULT hr = pUnknown->QueryInterface(IID_IMusepackSplitter, (void**)&demux);
+	if (FAILED(hr)) return hr;
+
+	// okej
+	return NOERROR;
+}
+
+HRESULT CMPCPropertyPage::OnDisconnect()
+{
+	if (demux) {
+		demux->Release(); demux = NULL;
+	}
+
+	return NOERROR;
+}
+
+HRESULT CMPCPropertyPage::OnActivate()
+{
+	demux->SetPropertyPageWindow(m_Dlg);
+
+	// initialize out controls
+	LVCOLUMN	col;
+	col.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
+
+	col.pszText = _T("Name");	col.cx = 150;	col.iSubItem = 0;
+	ListView_InsertColumn(ITEM(IDC_LIST_CONTENT), 0, &col);
+
+	col.pszText = _T("Value");	col.cx = 200;	col.iSubItem = 1;
+	ListView_InsertColumn(ITEM(IDC_LIST_CONTENT), 1, &col);
+
+	UpdateList();
+	return NOERROR;
+}
+
+HRESULT CMPCPropertyPage::OnDeactivate()
+{
+	demux->SetPropertyPageWindow(NULL);
+	return NOERROR;
+}
+
+void CMPCPropertyPage::UpdateList()
+{
+	// first reset everything
+	ListView_DeleteAllItems(ITEM(IDC_LIST_CONTENT));
+
+	// now check for the file
+	MPC_File_Info		info;
+	HRESULT hr = demux->GetFileInfo(&info);
+	if (FAILED(hr)) return ;
+
+	// now fill in the values
+	CString		name, val;
+	LVITEM		i;
+	int			item;
+
+	i.mask = LVIF_TEXT;
+	i.iSubItem = 0;
+
+	// Duration
+	i.pszText = _T("Duration");	i.iItem = 0;
+	MakeNiceTime(info.duration * 1000, val);
+	item = ListView_InsertItem(ITEM(IDC_LIST_CONTENT), &i);
+	ListView_SetItemText(ITEM(IDC_LIST_CONTENT), item, 1, val.GetBuffer());
+
+	// Stream version
+	i.pszText = _T("Stream version");	i.iItem = 1;
+	val.Format(_T("%d"), info.stream_version);
+	item = ListView_InsertItem(ITEM(IDC_LIST_CONTENT), &i);
+	ListView_SetItemText(ITEM(IDC_LIST_CONTENT), item, 1, val.GetBuffer());
+
+	// Stream version
+	i.pszText = _T("Sample rate");	i.iItem = 2;
+	val.Format(_T("%d Hz"), info.sample_rate);
+	item = ListView_InsertItem(ITEM(IDC_LIST_CONTENT), &i);
+	ListView_SetItemText(ITEM(IDC_LIST_CONTENT), item, 1, val.GetBuffer());
+
+	// Channels
+	i.pszText = _T("Channels");	i.iItem = 3;
+	val.Format(_T("%d"), info.channels);
+	item = ListView_InsertItem(ITEM(IDC_LIST_CONTENT), &i);
+	ListView_SetItemText(ITEM(IDC_LIST_CONTENT), item, 1, val.GetBuffer());
+
+	if (info.stream_version == 8) {
+
+		// Channels
+		i.pszText = _T("Frames per packet");	i.iItem = 4;
+		val.Format(_T("%d"), info.block_frames);
+		item = ListView_InsertItem(ITEM(IDC_LIST_CONTENT), &i);
+		ListView_SetItemText(ITEM(IDC_LIST_CONTENT), item, 1, val.GetBuffer());
+
+	}
+}
+
+
+INT_PTR CMPCPropertyPage::OnReceiveMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+	switch (uMsg) {
+	case WM_UPDATE_VISUALS:		UpdateList(); break;
+	}
+	return __super::OnReceiveMessage(hwnd, uMsg, wParam, lParam);
+}
+
Index: /dsfilters/demux_mpc/src/mpc_prop.h
===================================================================
--- /dsfilters/demux_mpc/src/mpc_prop.h	(revision 366)
+++ /dsfilters/demux_mpc/src/mpc_prop.h	(revision 366)
@@ -0,0 +1,40 @@
+//-----------------------------------------------------------------------------
+//
+//	Musepack Demuxer
+//
+//	Author : Igor Janos
+//
+//-----------------------------------------------------------------------------
+#pragma once
+
+
+#define WM_UPDATE_VISUALS		(WM_USER + 1003)
+
+//-----------------------------------------------------------------------------
+//
+//	CMPCPropertyPage class
+//
+//-----------------------------------------------------------------------------
+class CMPCPropertyPage : public CBasePropertyPage
+{
+public:
+
+	IMusepackSplitter		*demux;
+
+	void UpdateList();
+public:
+	CMPCPropertyPage(LPUNKNOWN lpUnk, HRESULT *phr);
+	virtual ~CMPCPropertyPage();
+	static CUnknown *WINAPI CreateInstance(LPUNKNOWN lpUnk, HRESULT *phr);
+
+	// CBasePropertyPage
+	HRESULT OnConnect(IUnknown *pUnknown);
+	HRESULT OnDisconnect();
+	HRESULT OnActivate();
+	HRESULT OnDeactivate();
+
+	// message
+	INT_PTR OnReceiveMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+};
+
+
Index: /dsfilters/demux_mpc/src/mpc_reg.cpp
===================================================================
--- /dsfilters/demux_mpc/src/mpc_reg.cpp	(revision 366)
+++ /dsfilters/demux_mpc/src/mpc_reg.cpp	(revision 366)
@@ -0,0 +1,106 @@
+//-----------------------------------------------------------------------------
+//
+//	Musepack Demuxer
+//
+//	Author : Igor Janos
+//
+//-----------------------------------------------------------------------------
+#include "stdafx.h"
+
+#pragma warning(disable: 4996)
+
+//-----------------------------------------------------------------------------
+//
+//	Registry Information
+//
+//-----------------------------------------------------------------------------
+
+
+const AMOVIESETUP_MEDIATYPE sudPinTypes[] =   
+		{ 
+			{
+				&MEDIATYPE_Stream,
+				&MEDIASUBTYPE_None
+			},
+			{
+				&MEDIATYPE_Stream,
+				&MEDIASUBTYPE_MusepackStream
+			},
+			{
+				&MEDIATYPE_Audio,
+				&MEDIASUBTYPE_MusepackPacket
+			}
+		};
+
+const AMOVIESETUP_PIN psudPins[] = 
+		{ 
+			{ 
+				L"Input",
+				FALSE,              // bRendered
+                FALSE,              // bOutput
+                FALSE,              // bZero
+                FALSE,              // bMany
+                &CLSID_NULL,        // clsConnectsToFilter
+                NULL,               // strConnectsToPin
+                2,                  // nTypes
+                &sudPinTypes[0]		// lpTypes
+			}      
+             , 
+			{ 
+				L"Output",          // strName
+                FALSE,              // bRendered
+                TRUE,               // bOutput
+                FALSE,              // bZero
+                TRUE,	            // bMany
+                &CLSID_NULL,        // clsConnectsToFilter
+                NULL,	            // strConnectsToPin
+                1,                  // nTypes
+                &sudPinTypes[2]		// lpTypes
+			} 
+		};   
+
+
+const AMOVIESETUP_FILTER sudMPCDemuxer = 
+		{ 
+			&CLSID_MusepackDemuxer,			// clsID
+            L"MONOGRAM Musepack Splitter",	// strName
+            MERIT_NORMAL,					// dwMerit
+            2,								// nPins
+            psudPins						// lpPin 
+		};                     
+
+CFactoryTemplate g_Templates[]=
+		{
+			{
+				L"MONOGRAM Musepack Splitter",
+				&CLSID_MusepackDemuxer,
+				CMPCDemux::CreateInstance, 
+				NULL,
+				&sudMPCDemuxer 
+			},
+			{
+				L"MONOGRAM Musepack Splitter",
+				&CLSID_MusepackDemuxPage,
+				CMPCPropertyPage::CreateInstance
+			}
+		};
+
+int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]);
+
+
+//-----------------------------------------------------------------------------
+//
+//	DLL Entry Points
+//
+//-----------------------------------------------------------------------------
+
+STDAPI DllRegisterServer() 
+{
+	return AMovieDllRegisterServer2(TRUE);
+}
+
+STDAPI DllUnregisterServer()
+{
+	return AMovieDllRegisterServer2(FALSE);
+}
+
Index: /dsfilters/demux_mpc/src/mpc_types.h
===================================================================
--- /dsfilters/demux_mpc/src/mpc_types.h	(revision 366)
+++ /dsfilters/demux_mpc/src/mpc_types.h	(revision 366)
@@ -0,0 +1,70 @@
+//-----------------------------------------------------------------------------
+//
+//	Musepack Demuxer
+//
+//	Author : Igor Janos
+//
+//-----------------------------------------------------------------------------
+#pragma once
+
+
+// {C3E2E983-0198-4f73-9E5C-8365BB4C4131}
+static const GUID CLSID_MusepackDemuxer = 
+{ 0xc3e2e983, 0x198, 0x4f73, { 0x9e, 0x5c, 0x83, 0x65, 0xbb, 0x4c, 0x41, 0x31 } };
+
+// {7E563A5E-12F1-45c1-A29F-032E21C2F7FC}
+static const GUID CLSID_MusepackDemuxPage = 
+{ 0x7e563a5e, 0x12f1, 0x45c1, { 0xa2, 0x9f, 0x3, 0x2e, 0x21, 0xc2, 0xf7, 0xfc } };
+
+
+//-----------------------------------------------------------------------------
+//
+//	Custom Media Types
+//
+//-----------------------------------------------------------------------------
+
+/*
+	The demuxer may connect with pull-mode source filters that may have
+	mechanism to identify file type. File Source (Async.) can do this
+	so we use MEDIATYPE_Stream/MEDIASUBTYPE_MusepackStream in such cases.
+	We will also accept unknown streams.
+
+	Demuxer itself must specify output type so the decoder can connect
+	properly. For output pin the demuxer will use
+	MEDIATYPE_Audio/MEDIASUBTYPE_MusepackPacket.
+*/
+
+// {0D2657B6-13B3-4c9b-AC9F-2EE055C51755}
+static const GUID MEDIASUBTYPE_MusepackPacket = 
+{ 0xd2657b6, 0x13b3, 0x4c9b, { 0xac, 0x9f, 0x2e, 0xe0, 0x55, 0xc5, 0x17, 0x55 } };
+
+// {229F9AD7-2F4D-4b45-B858-A3F434E7179A}
+static const GUID MEDIASUBTYPE_MusepackStream = 
+{ 0x229f9ad7, 0x2f4d, 0x4b45, { 0xb8, 0x58, 0xa3, 0xf4, 0x34, 0xe7, 0x17, 0x9a } };
+
+// {5751D1E7-D444-4c19-812C-A47352EDE8D2}
+static const GUID IID_IMusepackSplitter = 
+{ 0x5751d1e7, 0xd444, 0x4c19, { 0x81, 0x2c, 0xa4, 0x73, 0x52, 0xed, 0xe8, 0xd2 } };
+
+
+struct MPC_File_Info
+{
+	int		stream_version;			// 7, 8
+	double	duration;				// in seconds
+	int		sample_rate;
+	int		channels;
+	int		block_frames;			// frames per audio packet
+};
+
+
+
+DECLARE_INTERFACE_(IMusepackSplitter, IUnknown) 
+{
+	STDMETHOD(GetFileInfo)(MPC_File_Info *info) PURE;
+	STDMETHOD(SetPropertyPageWindow)(HWND wnd) PURE;
+};
+
+
+
+
+
Index: /dsfilters/demux_mpc/src/stdafx.h
===================================================================
--- /dsfilters/demux_mpc/src/stdafx.h	(revision 366)
+++ /dsfilters/demux_mpc/src/stdafx.h	(revision 366)
@@ -0,0 +1,61 @@
+//-----------------------------------------------------------------------------
+//
+//	Musepack Demuxer
+//
+//	Author : Igor Janos
+//
+//-----------------------------------------------------------------------------
+#pragma once
+
+#pragma warning(disable: 4996)
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER				// Allow use of features specific to Windows XP or later.
+#define WINVER 0x0501		// Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINNT		// Allow use of features specific to Windows XP or later.                   
+#define _WIN32_WINNT 0x0501	// Change this to the appropriate value to target other versions of Windows.
+#endif						
+
+#ifndef _WIN32_WINDOWS		// Allow use of features specific to Windows 98 or later.
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE			// Allow use of features specific to IE 6.0 or later.
+#define _WIN32_IE 0x0600	// Change this to the appropriate value to target other versions of IE.
+#endif
+
+#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS	// some CString constructors will be explicit
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#endif
+
+#include <afx.h>
+#include <afxwin.h>         // MFC core and standard components
+#include <afxext.h>         // MFC extensions
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxdtctl.h>		// MFC support for Internet Explorer 4 Common Controls
+#endif
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h>			// MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <iostream>
+#include <windows.h>
+
+#include <afxtempl.h>
+#include <streams.h>
+#include <initguid.h>
+#include <dvdmedia.h>
+
+#include "bits.h"
+#include "mpc_types.h"
+#include "mpc_file.h"
+#include "mpc_pin.h"
+#include "mpc_filter.h"
+#include "mpc_prop.h"
+
Index: /dsfilters/how-to-compile.txt
===================================================================
--- /dsfilters/how-to-compile.txt	(revision 366)
+++ /dsfilters/how-to-compile.txt	(revision 366)
@@ -0,0 +1,16 @@
+These filters have been developed under Visual Studio 2005 SP1.
+With installed Vista Platform SDK which contains baseclasses
+for DirectShow filters. 
+
+All filters link against 2 libraries which need to be compiled first
+from platform SDK:
+1. strmbasdu.lib - debug version of baseclasses. compiled with unicode support.
+2. strmbaseu.lib - release version of baseclasses. also compiled with unicode support.
+
+I have decided to include the libs I use, which also have
+patched support for MFC.
+
+In time I will add patched files as well as projects for VS 2003.
+
+
+Igor.
