changeset 2:105513a2e3c9

Import liboggplayer source.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 05 Aug 2013 13:50:20 +0300
parents 3562f296deb0
children acfb339ab87d
files liboggplayer-src/License.txt liboggplayer-src/bin/yuv2rgb.frag liboggplayer-src/bin/yuv2rgb.vert liboggplayer-src/examples/d3d9_oal.cpp liboggplayer-src/examples/ogl_glsl.cpp liboggplayer-src/examples/ogl_simple.cpp liboggplayer-src/examples/sdl_player.cpp liboggplayer-src/include/oggplayer.h liboggplayer-src/msvc/OGL_Simple/OGL_Simple.vcproj liboggplayer-src/msvc/OGL_Simple/OGL_Simple.vcproj.K2.Kambiz.user liboggplayer-src/msvc/SDL_Player/SDL_Player.vcproj liboggplayer-src/msvc/SDL_Player/SDL_Player.vcproj.K2.Kambiz.user liboggplayer-src/msvc/d3d9_oal/d3d9_oal.vcproj liboggplayer-src/msvc/d3d9_oal/d3d9_oal.vcproj.K2.Kambiz.user liboggplayer-src/msvc/liboggstream/liboggstream.vcproj liboggplayer-src/msvc/liboggstream/liboggstream.vcproj.K2.Kambiz.user liboggplayer-src/msvc/msvc.sln liboggplayer-src/msvc/msvc.suo liboggplayer-src/msvc/ogl_glsl/ogl_glsl.vcproj liboggplayer-src/msvc/ogl_glsl/ogl_glsl.vcproj.K2.Kambiz.user liboggplayer-src/sample video/readme-src.txt liboggplayer-src/sample video/readme.txt liboggplayer-src/src/SDL_audiocvt.cpp liboggplayer-src/src/SDL_audiocvt.hpp liboggplayer-src/src/imp.hpp liboggplayer-src/src/oggplayer.cpp liboggplayer-src/src/open_close.cpp liboggplayer-src/src/play.cpp liboggplayer-src/src/readme.txt liboggplayer-src/src/util.cpp
diffstat 30 files changed, 4651 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/License.txt	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,165 @@
+		   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions. 
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version. 
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/bin/yuv2rgb.frag	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,14 @@
+uniform sampler2D y_tex;
+uniform sampler2D u_tex;
+uniform sampler2D v_tex;
+
+void main (void)
+{
+	float y = texture2D(y_tex, vec2(gl_TexCoord[0])).r;
+	float u = texture2D(u_tex, vec2(gl_TexCoord[0])).r-0.5;
+	float v = texture2D(v_tex, vec2(gl_TexCoord[0])).r-0.5;
+	float r = y + 1.13983*v;
+	float g = y - 0.39465*u-0.58060*v;
+	float b = y + 2.03211*u;
+	gl_FragColor  = vec4(r,g,b,1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/bin/yuv2rgb.vert	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,6 @@
+void main(void)
+{
+   vec4 v = gl_Vertex;
+   gl_TexCoord[0] = gl_MultiTexCoord0;
+   gl_Position = gl_ModelViewProjectionMatrix * v;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/examples/d3d9_oal.cpp	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,270 @@
+//=========================================================================
+// Author      : Kambiz Veshgini
+// Description : Simple theora plyer using direct3d 9 and openal
+//=========================================================================
+
+#include <d3d9.h>
+#include <D3dx9math.h>
+#pragma warning( disable : 4996 ) // Disable deprecated warning 
+#include <strsafe.h>
+#pragma warning( default : 4996 )
+#include <oggplayer.h>
+#include <alut.h>
+
+// Use pragma for linking (MSVC only)
+#pragma comment(lib,"d3d9.lib")
+#pragma comment(lib,"d3dx9.lib")
+#ifdef _DEBUG
+	#pragma comment(lib,"liboggplayer-d.lib")
+#else
+	#pragma comment(lib,"liboggplayer.lib")
+#endif
+#pragma comment(lib,"alut.lib")
+#pragma comment(lib,"OpenAL32.lib")
+
+LPDIRECT3D9             g_pD3D = NULL;       
+LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; 
+LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;        
+LPDIRECT3DTEXTURE9      g_pTexture = NULL;   
+
+struct CUSTOMVERTEX
+{
+	FLOAT x, y, z, w;
+	D3DCOLOR color;
+	FLOAT tu, tv;
+};
+
+
+#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
+
+
+OggPlayer g_ogg; 
+
+HRESULT InitD3D( HWND hWnd )
+{
+	// Create the D3D object.
+	if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
+		return E_FAIL;
+
+	// Set up the structure used to create the D3DDevice
+	D3DPRESENT_PARAMETERS d3dpp;
+	ZeroMemory( &d3dpp, sizeof( d3dpp ) );
+	d3dpp.Windowed = TRUE;
+	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
+
+	// Create the D3DDevice
+	if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
+		D3DCREATE_SOFTWARE_VERTEXPROCESSING,
+		&d3dpp, &g_pd3dDevice ) ) )
+	{
+		return E_FAIL;
+	}
+
+	g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
+	g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+
+	// Create a dynamic texture
+	if( FAILED( D3DXCreateTexture(g_pd3dDevice,g_ogg.width(),g_ogg.height(),1,D3DUSAGE_DYNAMIC,D3DFMT_X8B8G8R8,D3DPOOL_DEFAULT,&g_pTexture)))
+	{
+		return E_FAIL;
+	}
+
+	float x1 = 0;
+	float y1 = 0;
+	float x2 = g_ogg.width();
+	float y2 = g_ogg.height();
+	// Initialize three vertices for rendering a quad
+	CUSTOMVERTEX vertices[] =
+	{   // x, y, z, color, tu, tv
+		{  x1,  y1, 0.0f, 1.0f, 0xffffffff, 0.0f, 0.0f }, 
+		{  x2,  y1, 0.0f, 1.0f, 0xffffffff, 1.0f, 0.0f },
+		{  x2,  y2, 0.0f, 1.0f, 0xffffffff, 1.0f, 1.0f },
+		{  x1,  y2, 0.0f, 1.0f, 0xffffffff, 0.0f, 1.0f },
+	};
+
+	if( FAILED( g_pd3dDevice->CreateVertexBuffer( 4 * sizeof( CUSTOMVERTEX ),
+		0, D3DFVF_CUSTOMVERTEX,
+		D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
+	{
+		return E_FAIL;
+	}
+
+	VOID* pVertices;
+	if( FAILED( g_pVB->Lock( 0, sizeof( vertices ), ( void** )&pVertices, 0 ) ) )
+		return E_FAIL;
+	memcpy( pVertices, vertices, sizeof( vertices ) );
+	g_pVB->Unlock();
+
+	return S_OK;
+}
+
+bool InitAL()
+{
+	alutInit(0, NULL);
+
+	int error = alGetError();
+	return error == AL_NO_ERROR ;
+}
+
+VOID Cleanup()
+{
+	if( g_pTexture != NULL )
+		g_pTexture->Release();
+
+	if( g_pVB != NULL )
+		g_pVB->Release();
+
+	if( g_pd3dDevice != NULL )
+		g_pd3dDevice->Release();
+
+	if( g_pD3D != NULL )
+		g_pD3D->Release();
+
+}
+
+VOID Render()
+{
+	D3DLOCKED_RECT lr;
+	if(SUCCEEDED(g_pTexture->LockRect(0,&lr,NULL,0)))
+	{
+		g_ogg.video_read((char*)lr.pBits,lr.Pitch);
+		g_pTexture->UnlockRect(0);
+	}
+
+	if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
+	{
+		g_pd3dDevice->SetTexture(0,g_pTexture);
+
+		g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
+		g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
+		g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );
+
+		g_pd3dDevice->EndScene();
+	}
+
+	g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
+}
+
+DWORD WINAPI MixAudio(LPVOID lpParameter )
+{
+	const int BUFFER_SIZE = 4096;
+	const int NUM_BUFFERS = 8;
+	char* pcm = new char[BUFFER_SIZE];
+	ALuint buffers[NUM_BUFFERS];
+	ALuint source;
+	int size;
+
+	alGenBuffers(NUM_BUFFERS, buffers);
+	alGenSources(1, &source);
+
+	for(int i=0;i<NUM_BUFFERS;i++){
+		size = g_ogg.audio_read(pcm,BUFFER_SIZE);
+		alBufferData(buffers[i], AL_FORMAT_STEREO16, pcm, size, 44100);
+	}
+	alSourceQueueBuffers(source, NUM_BUFFERS, buffers);
+	alSourcePlay(source);
+	while(g_ogg.playing())
+	{
+		int processed;
+		alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
+		
+		while((processed--)>0)
+		{
+			ALuint buffer;
+			alSourceUnqueueBuffers(source, 1, &buffer);
+			size = g_ogg.audio_read(pcm,BUFFER_SIZE);
+			if(size>0)
+				alBufferData(buffer, AL_FORMAT_STEREO16, pcm, size, 44100);
+			alSourceQueueBuffers(source, 1, &buffer);
+			ALenum state;
+			alGetSourcei(source, AL_SOURCE_STATE, &state);
+			if(state!=AL_PLAYING)
+				alSourcePlay(source);
+		}
+		Sleep(5);
+	}
+	alSourceStop(source);
+	alDeleteSources(1, &source);
+	alDeleteBuffers(NUM_BUFFERS, buffers);
+	delete [] pcm;
+	return 0;
+}
+
+LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
+{
+	switch( msg )
+	{
+	case WM_DESTROY:
+		Cleanup();
+		PostQuitMessage( 0 );
+		return 0;
+	}
+
+	return DefWindowProc( hWnd, msg, wParam, lParam );
+}
+
+
+INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
+{
+	g_ogg.open("../sample video/trailer_400p.ogg",AF_S16,2,44100,VF_BGRA);
+	if(g_ogg.fail()) {
+		return -1;
+	}
+
+	// Register the window class
+	WNDCLASSEX wc =
+	{
+		sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
+		GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
+		L"liboggstream", NULL
+	};
+
+	RegisterClassEx( &wc );
+
+
+	int width=g_ogg.width();
+	int height=g_ogg.height();
+	// Create the application's window
+	RECT rect;
+	rect.left = 100;
+	rect.top = 100;
+	rect.right = width+rect.left;
+	rect.bottom = height+rect.top;
+	AdjustWindowRect(&rect,WS_OVERLAPPEDWINDOW,FALSE);
+	HWND hWnd = CreateWindow( L"liboggstream", L"D3D9 Theora Player",
+		WS_OVERLAPPEDWINDOW, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
+		NULL, NULL, wc.hInstance, NULL );
+
+	// Initialize Direct3D and OpenAL
+	if( SUCCEEDED( InitD3D( hWnd ) ) && InitAL())
+	{
+		// Show the window
+		ShowWindow( hWnd, SW_SHOWDEFAULT );
+		UpdateWindow( hWnd );
+		// Start the playback
+		g_ogg.play();
+		// Run MixAudio in another thread
+		HANDLE h_mixaudio= CreateThread(NULL,0,MixAudio,NULL,0,NULL);
+		// Enter the message loop
+		MSG msg;
+		ZeroMemory( &msg, sizeof( msg ) );
+		while( msg.message != WM_QUIT && g_ogg.playing() )
+		{
+			if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
+			{
+				TranslateMessage( &msg );
+				DispatchMessage( &msg );
+			}else {
+				Render();
+				Sleep(0);
+			}
+		}
+		g_ogg.close();
+		WaitForSingleObject(h_mixaudio,INFINITE);
+		alutExit();
+	}
+
+	UnregisterClass( L"liboggstream", wc.hInstance );
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/examples/ogl_glsl.cpp	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,239 @@
+//=========================================================================
+// Author      : Kambiz Veshgini
+// Description : Opengl theora plyer; this sample uses a glsl shader for
+//               yuv to rgb conversion. See yuv2rgb.frag .
+//=========================================================================
+
+#include <oggplayer.h>
+#include <SDL/SDL_audio.h>
+#include <SDL/SDL.h>
+#ifdef _WINDOWS
+#include <windows.h>
+#endif
+#include <GL/glew.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <iostream>
+#include <algorithm>
+#include <fstream>
+#include <string>
+
+class YUV2RGBShader {
+public:
+	YUV2RGBShader() {
+        vert = glCreateShader(GL_VERTEX_SHADER);
+        frag = glCreateShader(GL_FRAGMENT_SHADER);
+    
+		std::string vs = read_file("yuv2rgb.vert");
+		std::string fs = read_file("yuv2rgb.frag");
+		const char* v_source = vs.c_str();
+		const char* f_source = fs.c_str();
+
+        glShaderSource(vert, 1, &v_source,NULL);
+        glShaderSource(frag, 1, &f_source,NULL);
+
+        glCompileShader(vert);
+        glCompileShader(frag);
+        
+		prog = glCreateProgram();
+		glAttachShader(prog,vert);
+		glAttachShader(prog,frag);
+	
+        glLinkProgram(prog);
+
+		y_pos = glGetUniformLocation(prog,"y_tex");
+		u_pos = glGetUniformLocation(prog,"u_tex");
+		v_pos = glGetUniformLocation(prog,"v_tex");
+	}
+	~YUV2RGBShader() {
+        glDeleteShader(vert);
+        glDeleteShader(frag);
+        glDeleteProgram(prog);
+	}
+	void bind_textures(GLuint y_tex, GLuint u_tex, GLuint v_tex) {
+		glActiveTexture(GL_TEXTURE0);
+		glBindTexture(GL_TEXTURE_2D, y_tex);
+		glUniform1i(y_pos, 0);
+		glActiveTexture(GL_TEXTURE1);
+		glBindTexture(GL_TEXTURE_2D, u_tex);
+		glUniform1i(u_pos, 1);
+		glActiveTexture(GL_TEXTURE2);
+		glBindTexture(GL_TEXTURE_2D, v_tex);
+		glUniform1i(v_pos, 2);
+	}
+    void use()
+    {
+        glUseProgram(prog);
+    }
+private:
+
+    std::string read_file(std::string path){
+        std::ifstream ifs(path.c_str(), std::ifstream::in);
+        if(!ifs.is_open()){
+            return "";
+        }
+        std::string s((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
+        ifs.close();
+        return s;
+    }
+    GLuint vert, frag, prog;
+	GLuint y_pos,u_pos,v_pos;
+};
+
+class YUVFrame {
+public:
+	YUVFrame(OggPlayer oggstream):ogg(oggstream), yuv2rgb_shader() {
+		width = ogg.width(); height = ogg.height();
+		// The textures are created when rendering the first frame
+		y_tex = u_tex = v_tex = -1 ;
+		// Thes variables help us render a fullscreen quad
+		// with the right aspect ration
+		const SDL_VideoInfo* vi = SDL_GetVideoInfo();
+		float max = std::max<float>((float)width/vi->current_w,(float)height/vi->current_h);
+		quad_w = width/max;
+		quad_h = height/max;
+		quad_x = (vi->current_w-quad_w)/2.0;
+		quad_y = (vi->current_h-quad_h)/2.0;
+	}
+	~YUVFrame() {
+		glDeleteTextures(1,&y_tex);
+		glDeleteTextures(1,&u_tex);
+		glDeleteTextures(1,&v_tex);
+	}
+	void render() {
+		update();
+		if(-1==y_tex) return; // not ready yet
+		yuv2rgb_shader.use();
+		yuv2rgb_shader.bind_textures(y_tex,u_tex,v_tex);
+		glBegin(GL_QUADS);
+		glTexCoord2f(0,1);glVertex2f(quad_x,quad_y);
+		glTexCoord2f(0,0);glVertex2f(quad_x,quad_y+quad_h);
+		glTexCoord2f(1,0);glVertex2f(quad_x+quad_w,quad_y+quad_h);
+		glTexCoord2f(1,1);glVertex2f(quad_x+quad_w,quad_y);
+		glEnd();
+	}
+private:
+	void update() {
+		YUVBuffer yuv;
+		// yuv_buffer_try_lock(...) returns false if the last read frame is
+		// still up to date, in this case we can simply retender the 
+		// last frame without an update
+		// We don't need to call unlock unless the lock operation was successfull
+		if(!ogg.yuv_buffer_try_lock(&yuv)) return;
+		// Create the textures if needed, at this point we 
+		// know how big the textures should be.
+		// The sample plyer that comes with the official SDK
+		// assummes uv_width=y_width/2 , uv_height=y_height/2
+		// but I'm not sure whether that is always true
+		if(-1==y_tex){
+			y_tex = gen_texture(yuv.y_width,yuv.y_height);
+			u_tex = gen_texture(yuv.uv_width,yuv.uv_height);
+			v_tex = gen_texture(yuv.uv_width,yuv.uv_height);
+		}
+		int y_offset = ogg.offset_x() + yuv.y_stride * ogg.offset_y();
+		int uv_offset = ogg.offset_x()/(yuv.y_width/yuv.uv_width)+
+			yuv.uv_stride * ogg.offset_y()/(yuv.y_height/yuv.uv_height);
+		update_texture(y_tex,yuv.y+y_offset,yuv.y_width,yuv.y_height,yuv.y_stride);
+		update_texture(u_tex,yuv.u+uv_offset,yuv.uv_width,yuv.uv_height,yuv.uv_stride);
+		update_texture(v_tex,yuv.v+uv_offset,yuv.uv_width,yuv.uv_height,yuv.uv_stride);
+		ogg.yuv_buffer_unlock();
+	}
+	GLuint gen_texture(int w,int h) {
+		GLuint tex;
+		glGenTextures(1,&tex);
+		glBindTexture(GL_TEXTURE_2D,tex);
+		glTexImage2D(GL_TEXTURE_2D,0,1,w,h,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,NULL);
+		glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+		glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+		glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT );
+		glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT );
+		return tex;
+	}
+	void update_texture(GLuint tex, unsigned char* buf,int w,int h, int stride) {
+		glPixelStorei(GL_UNPACK_ROW_LENGTH,stride);
+		glBindTexture(GL_TEXTURE_2D,tex);
+		glTexSubImage2D(GL_TEXTURE_2D,0,0,0,w,h,GL_LUMINANCE,GL_UNSIGNED_BYTE,buf);
+		// set GL_UNPACK_ROW_LENGTH back to 0 to avoid bugs 
+		glPixelStorei(GL_UNPACK_ROW_LENGTH,0);
+	}
+	YUV2RGBShader yuv2rgb_shader;
+	OggPlayer ogg;
+	GLuint y_tex,u_tex,v_tex;
+	int width,height;
+	float quad_w,quad_h,quad_x,quad_y;
+};
+
+void mixaudio(void *data, Uint8 *stream, int len) {
+	OggPlayer* ogg=(OggPlayer*)data;
+	ogg->audio_read((char*)stream,len);
+}
+
+bool init_audio(void* user_data) {
+	SDL_AudioSpec fmt;
+	fmt.freq = 44100;
+	fmt.format = AUDIO_S16;
+	fmt.channels = 2;
+	fmt.samples = 512;
+	fmt.callback = mixaudio;
+	fmt.userdata = user_data;
+
+	if (SDL_OpenAudio(&fmt, NULL) < 0) return false;
+	SDL_PauseAudio(0);
+
+	return true;
+}
+
+bool init_video(int w, int h){
+	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) return false;
+	const SDL_VideoInfo* vi = SDL_GetVideoInfo();
+	SDL_SetVideoMode(vi->current_w, vi->current_h, 0, SDL_OPENGL | SDL_FULLSCREEN);
+	glEnable(GL_TEXTURE_2D);
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	gluOrtho2D(0,vi->current_w,0,vi->current_h);
+	return true;
+}
+
+void on_exit(){
+	std::string error(SDL_GetError());
+	if(!error.empty())
+		std::cerr << "Error: "<< error << std::endl;
+	SDL_CloseAudio();
+	SDL_Quit();
+}
+
+int main( int argc, char* argv[] ) {
+	atexit(on_exit);
+
+	OggPlayer ogg("../sample video/trailer_400p.ogg",AF_S16,2,44100,VF_BGRA);
+	if(ogg.fail()) {
+		SDL_SetError("Could not open ../sample video/trailer_400p.ogg");
+		return -2;
+	}
+
+	if(!init_audio((void*)&ogg) || !init_video(ogg.width(),ogg.height()))
+		return -3;
+
+	glewInit();
+
+	if (!GLEW_VERSION_2_0){
+		SDL_SetError("OpenGL 2.0 not supported");
+		return -1;
+	}
+
+	YUVFrame yuv_frame(ogg);
+
+	ogg.play();
+
+	bool running=true;
+
+	while( ogg.playing() && running ) {
+		SDL_Event event;
+		while(SDL_PollEvent(&event)){
+			if(event.type==SDL_QUIT || event.type==SDL_KEYDOWN){ running = false; }
+		}
+		yuv_frame.render();
+		SDL_GL_SwapBuffers();
+	}
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/examples/ogl_simple.cpp	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,123 @@
+//=========================================================================
+// Author      : Kambiz Veshgini
+// Description : Simple opengl theora plyer
+//=========================================================================
+
+#include <oggplayer.h>
+#include <SDL/SDL_audio.h>
+#include <SDL/SDL.h>
+#ifdef _WINDOWS
+	#include <windows.h>
+#endif
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <iostream>
+#include <algorithm>
+#include <vector>
+
+void mixaudio(void *data, Uint8 *stream, int len) {
+	OggPlayer* ogg=(OggPlayer*)data;
+	ogg->audio_read((char*)stream,len);
+}
+
+bool init_audio(void* user_data) {
+	SDL_AudioSpec fmt;
+	fmt.freq = 44100;
+	fmt.format = AUDIO_S16;
+	fmt.channels = 2;
+	fmt.samples = 512;
+	fmt.callback = mixaudio;
+	fmt.userdata = user_data;
+
+	if (SDL_OpenAudio(&fmt, NULL) < 0) return false;
+	SDL_PauseAudio(0);
+
+	return true;
+}
+
+bool init_video(int w, int h){
+	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) return false;
+	const SDL_VideoInfo* vi = SDL_GetVideoInfo();
+	SDL_SetVideoMode(vi->current_w, vi->current_h, 0, SDL_OPENGL | SDL_FULLSCREEN);
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	gluOrtho2D(0,vi->current_w,0,vi->current_h);
+	return true;
+}
+
+void on_exit(){
+	std::string error(SDL_GetError());
+	if(!error.empty())
+		std::cerr << "Error: "<< error << std::endl;
+	SDL_CloseAudio();
+	SDL_Quit();
+}
+
+int main( int argc, char* argv[] ) {
+	atexit(on_exit);
+	// OggPlayer will automatically convert the audio and video
+	// to the spcified formats
+	OggPlayer ogg("../sample video/trailer_400p.ogg",AF_S16,2,44100,VF_BGRA);
+	if(ogg.fail()) {
+		SDL_SetError("Could not open ../sample video/trailer_400p.ogg");
+		return -1;
+	}
+
+	if(!init_audio((void*)&ogg) || !init_video(ogg.width(),ogg.height()))
+		return -2;
+
+	// creat an opengl texture, we assume non power of two textures are
+	// supported (opengl 2.0)
+	GLuint tex;
+	glEnable(GL_TEXTURE_2D);
+	glGenTextures(1,&tex);
+	glBindTexture(GL_TEXTURE_2D,tex);
+	glTexImage2D(GL_TEXTURE_2D,0,4,ogg.width(),ogg.height(),0,GL_BGRA_EXT,GL_BYTE,NULL);
+	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
+	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
+	
+	// start the playback
+	ogg.play();
+	
+	// the quad_? variables are used to draw our textured quad
+	const SDL_VideoInfo* vi = SDL_GetVideoInfo();
+	float max = std::max<float>((float)ogg.width()/vi->current_w,(float)ogg.height()/vi->current_h);
+	float quad_w = ogg.width()/max;
+	float quad_h = ogg.height()/max;
+	float quad_x = (vi->current_w-quad_w)/2.0;
+	float quad_y = (vi->current_h-quad_h)/2.0;
+
+	bool running=true;
+	while( ogg.playing() && running ) {
+		std::vector<char> bgra_buffer(ogg.width()*ogg.height()*4);
+		
+		// exit on key down
+		SDL_Event event;
+		while(SDL_PollEvent(&event))
+			if(event.type==SDL_QUIT || event.type==SDL_KEYDOWN){ running = false; }
+
+		glBindTexture(GL_TEXTURE_2D,tex);
+		
+		// read a frame, video_read(...) returns false if the last read frame is
+		// still up to date, thus we only opdate the texture if we get new data
+		if(ogg.video_read(&bgra_buffer[0]))
+			glTexSubImage2D(GL_TEXTURE_2D,0,0,0,ogg.width(),ogg.height(),GL_BGRA_EXT,GL_UNSIGNED_BYTE,&bgra_buffer[0]);
+		
+		// draw a textured quad
+		glBegin(GL_QUADS);
+		glTexCoord2f(0,1);glVertex2f(quad_x,quad_y);
+		glTexCoord2f(0,0);glVertex2f(quad_x,quad_y+quad_h);
+		glTexCoord2f(1,0);glVertex2f(quad_x+quad_w,quad_y+quad_h);
+		glTexCoord2f(1,1);glVertex2f(quad_x+quad_w,quad_y);
+		glEnd();
+
+		SDL_GL_SwapBuffers();
+		
+		// let the play thread decode some data
+		SDL_Delay(0);
+	}
+	glDeleteTextures(1,&tex);
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/examples/sdl_player.cpp	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,74 @@
+//=========================================================================
+// Author      : Kambiz Veshgini
+// Description : Simple SDL theora plyer, this sample does not use a
+//               yuv overlay 
+//=========================================================================
+
+#include <oggplayer.h>
+#include <SDL/SDL_audio.h>
+#include <SDL/SDL.h>
+#include <iostream>
+
+
+void mixaudio(void *data, Uint8 *stream, int len) {
+	OggPlayer* ogg=(OggPlayer*)data;
+	ogg->audio_read((char*)stream,len);
+}
+
+bool init_audio(void* user_data) {
+    SDL_AudioSpec fmt;
+    fmt.freq = 44100;
+    fmt.format = AUDIO_S16;
+    fmt.channels = 2;
+    fmt.samples = 512;
+    fmt.callback = mixaudio;
+    fmt.userdata = user_data;
+
+    if (SDL_OpenAudio(&fmt, NULL) < 0) return false;
+    SDL_PauseAudio(0);
+
+    return true;
+}
+
+SDL_Surface* init_video(int w, int h){
+  if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) return NULL;
+  return SDL_SetVideoMode(w, h, 0, SDL_SWSURFACE);
+}
+
+void on_exit(){
+	std::string error(SDL_GetError());
+	if(!error.empty())
+		std::cerr << "Error: "<< error << std::endl;
+	SDL_CloseAudio();
+	SDL_Quit();
+}
+
+int main( int argc, char* argv[] ) {
+	atexit(on_exit);
+
+	OggPlayer ogg("../sample video/trailer_400p.ogg",AF_S16,2,44100,VF_BGRA);
+	if(ogg.fail()) {
+		SDL_SetError("Could not open ../sample video/trailer_400p.ogg");
+		return -1;
+	}
+
+	SDL_Surface *screen;
+	if(!init_audio((void*)&ogg) || !(screen=init_video(ogg.width(),ogg.height())))
+		  return -2;
+
+	ogg.play();
+
+	bool running=true;
+	while( ogg.playing() && running ) {
+		SDL_Event event;
+		while(SDL_PollEvent(&event))
+			if(event.type==SDL_QUIT){ running = false; }
+
+	    SDL_LockSurface( screen );
+		ogg.video_read((char*)screen->pixels,screen->pitch);
+	    SDL_UnlockSurface( screen );
+		SDL_Flip(screen);
+		SDL_Delay(0);
+	}
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/include/oggplayer.h	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,75 @@
+//=========================================================================
+// Author      : Kambiz Veshgini
+// License     : This library is distributed in the hope that it will be 
+//               useful, but WITHOUT ANY WARRANTY; without even the implied 
+//               warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+//               PURPOSE.  See the GNU Lesser General Public License for 
+//               more details.
+//=========================================================================
+
+#ifndef OGGSTREAM_H_
+#define OGGSTREAM_H_
+
+#include <string>
+
+#if defined(MSVC_COMPILING_DLL)
+	#define DLL __declspec(dllexport)
+#else
+	#define DLL
+#endif
+// These formats are equivalent to those used in SDL_audio
+enum AudioFormat {
+	AF_U8 = 0x0008,
+	AF_S8 = 0x8008,
+	AF_U16LSB = 0x0010,
+	AF_S16LSB = 0x8010,
+	AF_U16MSB = 0x1010,
+	AF_S16MSB = 0x9010,
+	AF_U16 = 0x0010,
+	AF_S16 = 0x8010
+};
+
+enum VideoFormat {
+	VF_RGB, VF_BGR, VF_RGBA, VF_BGRA
+};
+
+struct YUVBuffer {
+	int y_width;
+	int y_height;
+	int y_stride;
+	int uv_width;
+	int uv_height;
+	int uv_stride;
+	unsigned char *y;
+	unsigned char *u;
+	unsigned char *v;
+};
+
+class OggPlayer {
+public:
+	DLL ~OggPlayer();
+	DLL OggPlayer();
+	DLL OggPlayer(OggPlayer& ogg);
+	DLL OggPlayer& operator =(OggPlayer& os);
+	DLL OggPlayer(std::string path, AudioFormat audio_format, int channels,
+			int rate, VideoFormat video_format=VF_BGRA);
+	DLL void open(std::string path, AudioFormat audio_format, int channels,
+			int rate, VideoFormat video_format=VF_BGRA);
+	DLL void close();
+	DLL bool fail();
+	DLL void play();
+	DLL bool playing();
+	DLL int audio_read(char* buf, unsigned int size);
+	DLL bool yuv_buffer_try_lock(YUVBuffer *buffer);
+	DLL void yuv_buffer_unlock();
+	DLL bool video_read(char* buf, int stride=0);
+	DLL int width();
+	DLL int height();
+	DLL int offset_x();
+	DLL int offset_y();
+private:
+	struct Imp;
+	Imp* imp;
+};
+
+#endif /* OGGSTREAM_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/msvc/OGL_Simple/OGL_Simple.vcproj	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="ogl_simple"
+	ProjectGUID="{37BA4571-8EAF-46AD-B89C-AFE1A9C01F0F}"
+	RootNamespace="OGL_Simple"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="SDL.lib SDLmain.lib  liboggplayer-d.lib opengl32.lib glu32.lib"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="../../lib"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories="../../include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="SDL.lib SDLmain.lib  liboggplayer.lib opengl32.lib glu32.lib"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../lib"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="copy $(OutDir)\*.exe $(InputDir)\..\..\bin\"
+			/>
+		</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="..\..\examples\ogl_simple.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+		</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}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/msvc/OGL_Simple/OGL_Simple.vcproj.K2.Kambiz.user	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioUserFile
+	ProjectType="Visual C++"
+	Version="9,00"
+	ShowAllFiles="false"
+	>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			>
+			<DebugSettings
+				Command="$(TargetPath)"
+				WorkingDirectory="../../bin"
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="K2"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment=""
+				EnvironmentMerge="true"
+				DebuggerFlavor="0"
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			>
+			<DebugSettings
+				Command="$(TargetPath)"
+				WorkingDirectory="../../bin"
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="K2"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment=""
+				EnvironmentMerge="true"
+				DebuggerFlavor="0"
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+	</Configurations>
+</VisualStudioUserFile>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/msvc/SDL_Player/SDL_Player.vcproj	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="sdl_player"
+	ProjectGUID="{4F7B4465-84D7-47F3-9EE3-C62F1F4403C0}"
+	RootNamespace="SDL_Player"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="SDL.lib SDLmain.lib  liboggplayer-d.lib"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="../../lib"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories="../../include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="SDL.lib SDLmain.lib  liboggplayer.lib"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../lib"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				EntryPointSymbol=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="copy $(OutDir)\*.exe $(InputDir)\..\..\bin\"
+			/>
+		</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="..\..\examples\sdl_player.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+		</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}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/msvc/SDL_Player/SDL_Player.vcproj.K2.Kambiz.user	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioUserFile
+	ProjectType="Visual C++"
+	Version="9,00"
+	ShowAllFiles="false"
+	>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			>
+			<DebugSettings
+				Command="$(TargetPath)"
+				WorkingDirectory="../../bin"
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="K2"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment=""
+				EnvironmentMerge="true"
+				DebuggerFlavor="0"
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			>
+			<DebugSettings
+				Command="$(TargetPath)"
+				WorkingDirectory="../../bin"
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="K2"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment=""
+				EnvironmentMerge="true"
+				DebuggerFlavor="0"
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+	</Configurations>
+</VisualStudioUserFile>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/msvc/d3d9_oal/d3d9_oal.vcproj	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="d3d9_oal"
+	ProjectGUID="{08AAE044-C392-412D-A6B0-6D5C09DA8431}"
+	RootNamespace="d3d9_oal"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="../../lib"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories="../../include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../lib"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="copy $(OutDir)\*.exe $(InputDir)\..\..\bin\"
+			/>
+		</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="..\..\examples\d3d9_oal.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+		</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}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/msvc/d3d9_oal/d3d9_oal.vcproj.K2.Kambiz.user	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioUserFile
+	ProjectType="Visual C++"
+	Version="9,00"
+	ShowAllFiles="false"
+	>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			>
+			<DebugSettings
+				Command="$(TargetPath)"
+				WorkingDirectory="../../bin"
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="K2"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment=""
+				EnvironmentMerge="true"
+				DebuggerFlavor="0"
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			>
+			<DebugSettings
+				Command="$(TargetPath)"
+				WorkingDirectory="../../bin"
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="K2"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment=""
+				EnvironmentMerge="true"
+				DebuggerFlavor="0"
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+	</Configurations>
+</VisualStudioUserFile>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/msvc/liboggstream/liboggstream.vcproj	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="liboggplayer"
+	ProjectGUID="{598C2712-7AD4-4F48-9B85-64342EF1E76D}"
+	RootNamespace="liboggstream"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBOGGSTREAM_EXPORTS;MSVC_COMPILING_DLL"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ogg_static.lib vorbis_static.lib theora_static.lib winmm.lib"
+				OutputFile="$(OutDir)\liboggplayer-d.dll"
+				LinkIncremental="2"
+				IgnoreDefaultLibraryNames="LIBCMT"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="copy $(OutDir)\*.dll $(InputDir)\..\..\bin\&#x0D;&#x0A;copy $(OutDir)\*.lib $(InputDir)\..\..\lib\&#x0D;&#x0A;"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+				CommandLine="copy $(OutDir)\*.exe $(InputDir)\..\..\bin\&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				FavorSizeOrSpeed="1"
+				AdditionalIncludeDirectories="../../include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBOGGSTREAM_EXPORTS;MSVC_COMPILING_DLL"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="vorbis_static.lib theora_static.lib ogg_static.lib winmm.lib"
+				OutputFile="$(OutDir)\liboggplayer.dll"
+				LinkIncremental="1"
+				IgnoreDefaultLibraryNames="LIBCMT"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="copy $(OutDir)\*.dll $(InputDir)\..\..\bin\&#x0D;&#x0A;copy $(OutDir)\*.lib $(InputDir)\..\..\lib\&#x0D;&#x0A;"
+			/>
+		</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\oggplayer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\open_close.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\play.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\SDL_audiocvt.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\util.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\..\src\imp.hpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\include\oggplayer.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\SDL_audiocvt.hpp"
+				>
+			</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}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/msvc/liboggstream/liboggstream.vcproj.K2.Kambiz.user	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioUserFile
+	ProjectType="Visual C++"
+	Version="9,00"
+	ShowAllFiles="false"
+	>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			>
+			<DebugSettings
+				Command=""
+				WorkingDirectory=""
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="K2"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment=""
+				EnvironmentMerge="true"
+				DebuggerFlavor=""
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			>
+			<DebugSettings
+				Command=""
+				WorkingDirectory=""
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="K2"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment=""
+				EnvironmentMerge="true"
+				DebuggerFlavor=""
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+	</Configurations>
+</VisualStudioUserFile>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/msvc/msvc.sln	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,44 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liboggstream", "liboggstream\liboggstream.vcproj", "{598C2712-7AD4-4F48-9B85-64342EF1E76D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdl_player", "SDL_Player\SDL_Player.vcproj", "{4F7B4465-84D7-47F3-9EE3-C62F1F4403C0}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ogl_simple", "OGL_Simple\OGL_Simple.vcproj", "{37BA4571-8EAF-46AD-B89C-AFE1A9C01F0F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ogl_glsl", "ogl_glsl\ogl_glsl.vcproj", "{0C17E951-71C9-4F2E-9635-17FB25FCCDEB}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "d3d9_oal", "d3d9_oal\d3d9_oal.vcproj", "{08AAE044-C392-412D-A6B0-6D5C09DA8431}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{598C2712-7AD4-4F48-9B85-64342EF1E76D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{598C2712-7AD4-4F48-9B85-64342EF1E76D}.Debug|Win32.Build.0 = Debug|Win32
+		{598C2712-7AD4-4F48-9B85-64342EF1E76D}.Release|Win32.ActiveCfg = Release|Win32
+		{598C2712-7AD4-4F48-9B85-64342EF1E76D}.Release|Win32.Build.0 = Release|Win32
+		{4F7B4465-84D7-47F3-9EE3-C62F1F4403C0}.Debug|Win32.ActiveCfg = Debug|Win32
+		{4F7B4465-84D7-47F3-9EE3-C62F1F4403C0}.Debug|Win32.Build.0 = Debug|Win32
+		{4F7B4465-84D7-47F3-9EE3-C62F1F4403C0}.Release|Win32.ActiveCfg = Release|Win32
+		{4F7B4465-84D7-47F3-9EE3-C62F1F4403C0}.Release|Win32.Build.0 = Release|Win32
+		{37BA4571-8EAF-46AD-B89C-AFE1A9C01F0F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{37BA4571-8EAF-46AD-B89C-AFE1A9C01F0F}.Debug|Win32.Build.0 = Debug|Win32
+		{37BA4571-8EAF-46AD-B89C-AFE1A9C01F0F}.Release|Win32.ActiveCfg = Release|Win32
+		{37BA4571-8EAF-46AD-B89C-AFE1A9C01F0F}.Release|Win32.Build.0 = Release|Win32
+		{0C17E951-71C9-4F2E-9635-17FB25FCCDEB}.Debug|Win32.ActiveCfg = Debug|Win32
+		{0C17E951-71C9-4F2E-9635-17FB25FCCDEB}.Debug|Win32.Build.0 = Debug|Win32
+		{0C17E951-71C9-4F2E-9635-17FB25FCCDEB}.Release|Win32.ActiveCfg = Release|Win32
+		{0C17E951-71C9-4F2E-9635-17FB25FCCDEB}.Release|Win32.Build.0 = Release|Win32
+		{08AAE044-C392-412D-A6B0-6D5C09DA8431}.Debug|Win32.ActiveCfg = Debug|Win32
+		{08AAE044-C392-412D-A6B0-6D5C09DA8431}.Debug|Win32.Build.0 = Debug|Win32
+		{08AAE044-C392-412D-A6B0-6D5C09DA8431}.Release|Win32.ActiveCfg = Release|Win32
+		{08AAE044-C392-412D-A6B0-6D5C09DA8431}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Binary file liboggplayer-src/msvc/msvc.suo has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/msvc/ogl_glsl/ogl_glsl.vcproj	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="ogl_glsl"
+	ProjectGUID="{0C17E951-71C9-4F2E-9635-17FB25FCCDEB}"
+	RootNamespace="ogl_glsl"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="SDL.lib SDLmain.lib liboggplayer-d.lib opengl32.lib glu32.lib glew32.lib"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="..\..\lib"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories="..\..\include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="SDL.lib SDLmain.lib liboggplayer.lib opengl32.lib glu32.lib glew32.lib"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="..\..\lib"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="copy $(OutDir)\*.exe $(InputDir)\..\..\bin\"
+			/>
+		</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="..\..\examples\ogl_glsl.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+		</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}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/msvc/ogl_glsl/ogl_glsl.vcproj.K2.Kambiz.user	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioUserFile
+	ProjectType="Visual C++"
+	Version="9,00"
+	ShowAllFiles="false"
+	>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			>
+			<DebugSettings
+				Command="$(TargetPath)"
+				WorkingDirectory="..\..\bin"
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="K2"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment=""
+				EnvironmentMerge="true"
+				DebuggerFlavor="0"
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			>
+			<DebugSettings
+				Command="$(TargetPath)"
+				WorkingDirectory="..\..\bin"
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="K2"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment=""
+				EnvironmentMerge="true"
+				DebuggerFlavor="0"
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+	</Configurations>
+</VisualStudioUserFile>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/sample video/readme-src.txt	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,2 @@
+Sample video is not included in the source only package, but it can be downloaded from 
+http://www.bigbuckbunny.org/index.php/trailer-page/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/sample video/readme.txt	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,2 @@
+trailer_400p.ogg is the trailer for the open movie "Big Buck Bunny".
+(c) copyright Blender Foundation | www.bigbuckbunny.org
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/src/SDL_audiocvt.cpp	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,1509 @@
+/*
+	This is a modified version of SDL_audiocvt.c from SDL 1.2.13
+	It does not depend on any other files from SDL
+*/
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2006 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+#include "SDL_audiocvt.hpp"
+
+/* Effectively mix right and left channels into a single channel */
+void  SDL_ConvertMono(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Sint32 sample;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting to mono\n");
+#endif
+	switch (format&0x8018) {
+
+		case AUDIO_U8: {
+			Uint8 *src, *dst;
+
+			src = cvt->buf;
+			dst = cvt->buf;
+			for ( i=cvt->len_cvt/2; i; --i ) {
+				sample = src[0] + src[1];
+				*dst = (Uint8)(sample / 2);
+				src += 2;
+				dst += 1;
+			}
+		}
+		break;
+
+		case AUDIO_S8: {
+			Sint8 *src, *dst;
+
+			src = (Sint8 *)cvt->buf;
+			dst = (Sint8 *)cvt->buf;
+			for ( i=cvt->len_cvt/2; i; --i ) {
+				sample = src[0] + src[1];
+				*dst = (Sint8)(sample / 2);
+				src += 2;
+				dst += 1;
+			}
+		}
+		break;
+
+		case AUDIO_U16: {
+			Uint8 *src, *dst;
+
+			src = cvt->buf;
+			dst = cvt->buf;
+			if ( (format & 0x1000) == 0x1000 ) {
+				for ( i=cvt->len_cvt/4; i; --i ) {
+					sample = (Uint16)((src[0]<<8)|src[1])+
+					         (Uint16)((src[2]<<8)|src[3]);
+					sample /= 2;
+					dst[1] = (sample&0xFF);
+					sample >>= 8;
+					dst[0] = (sample&0xFF);
+					src += 4;
+					dst += 2;
+				}
+			} else {
+				for ( i=cvt->len_cvt/4; i; --i ) {
+					sample = (Uint16)((src[1]<<8)|src[0])+
+					         (Uint16)((src[3]<<8)|src[2]);
+					sample /= 2;
+					dst[0] = (sample&0xFF);
+					sample >>= 8;
+					dst[1] = (sample&0xFF);
+					src += 4;
+					dst += 2;
+				}
+			}
+		}
+		break;
+
+		case AUDIO_S16: {
+			Uint8 *src, *dst;
+
+			src = cvt->buf;
+			dst = cvt->buf;
+			if ( (format & 0x1000) == 0x1000 ) {
+				for ( i=cvt->len_cvt/4; i; --i ) {
+					sample = (Sint16)((src[0]<<8)|src[1])+
+					         (Sint16)((src[2]<<8)|src[3]);
+					sample /= 2;
+					dst[1] = (sample&0xFF);
+					sample >>= 8;
+					dst[0] = (sample&0xFF);
+					src += 4;
+					dst += 2;
+				}
+			} else {
+				for ( i=cvt->len_cvt/4; i; --i ) {
+					sample = (Sint16)((src[1]<<8)|src[0])+
+					         (Sint16)((src[3]<<8)|src[2]);
+					sample /= 2;
+					dst[0] = (sample&0xFF);
+					sample >>= 8;
+					dst[1] = (sample&0xFF);
+					src += 4;
+					dst += 2;
+				}
+			}
+		}
+		break;
+	}
+	cvt->len_cvt /= 2;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+/* Discard top 4 channels */
+void  SDL_ConvertStrip(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Sint32 lsample, rsample;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting down to stereo\n");
+#endif
+	switch (format&0x8018) {
+
+		case AUDIO_U8: {
+			Uint8 *src, *dst;
+
+			src = cvt->buf;
+			dst = cvt->buf;
+			for ( i=cvt->len_cvt/6; i; --i ) {
+				dst[0] = src[0];
+				dst[1] = src[1];
+				src += 6;
+				dst += 2;
+			}
+		}
+		break;
+
+		case AUDIO_S8: {
+			Sint8 *src, *dst;
+
+			src = (Sint8 *)cvt->buf;
+			dst = (Sint8 *)cvt->buf;
+			for ( i=cvt->len_cvt/6; i; --i ) {
+				dst[0] = src[0];
+				dst[1] = src[1];
+				src += 6;
+				dst += 2;
+			}
+		}
+		break;
+
+		case AUDIO_U16: {
+			Uint8 *src, *dst;
+
+			src = cvt->buf;
+			dst = cvt->buf;
+			if ( (format & 0x1000) == 0x1000 ) {
+				for ( i=cvt->len_cvt/12; i; --i ) {
+					lsample = (Uint16)((src[0]<<8)|src[1]);
+					rsample = (Uint16)((src[2]<<8)|src[3]);
+						dst[1] = (lsample&0xFF);
+						lsample >>= 8;
+						dst[0] = (lsample&0xFF);
+						dst[3] = (rsample&0xFF);
+						rsample >>= 8;
+						dst[2] = (rsample&0xFF);
+					src += 12;
+					dst += 4;
+				}
+			} else {
+				for ( i=cvt->len_cvt/12; i; --i ) {
+					lsample = (Uint16)((src[1]<<8)|src[0]);
+					rsample = (Uint16)((src[3]<<8)|src[2]);
+						dst[0] = (lsample&0xFF);
+						lsample >>= 8;
+						dst[1] = (lsample&0xFF);
+						dst[2] = (rsample&0xFF);
+						rsample >>= 8;
+						dst[3] = (rsample&0xFF);
+					src += 12;
+					dst += 4;
+				}
+			}
+		}
+		break;
+
+		case AUDIO_S16: {
+			Uint8 *src, *dst;
+
+			src = cvt->buf;
+			dst = cvt->buf;
+			if ( (format & 0x1000) == 0x1000 ) {
+				for ( i=cvt->len_cvt/12; i; --i ) {
+					lsample = (Sint16)((src[0]<<8)|src[1]);
+					rsample = (Sint16)((src[2]<<8)|src[3]);
+						dst[1] = (lsample&0xFF);
+						lsample >>= 8;
+						dst[0] = (lsample&0xFF);
+						dst[3] = (rsample&0xFF);
+						rsample >>= 8;
+						dst[2] = (rsample&0xFF);
+					src += 12;
+					dst += 4;
+				}
+			} else {
+				for ( i=cvt->len_cvt/12; i; --i ) {
+					lsample = (Sint16)((src[1]<<8)|src[0]);
+					rsample = (Sint16)((src[3]<<8)|src[2]);
+						dst[0] = (lsample&0xFF);
+						lsample >>= 8;
+						dst[1] = (lsample&0xFF);
+						dst[2] = (rsample&0xFF);
+						rsample >>= 8;
+						dst[3] = (rsample&0xFF);
+					src += 12;
+					dst += 4;
+				}
+			}
+		}
+		break;
+	}
+	cvt->len_cvt /= 3;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+
+/* Discard top 2 channels of 6 */
+void  SDL_ConvertStrip_2(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Sint32 lsample, rsample;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting 6 down to quad\n");
+#endif
+	switch (format&0x8018) {
+
+		case AUDIO_U8: {
+			Uint8 *src, *dst;
+
+			src = cvt->buf;
+			dst = cvt->buf;
+			for ( i=cvt->len_cvt/4; i; --i ) {
+				dst[0] = src[0];
+				dst[1] = src[1];
+				src += 4;
+				dst += 2;
+			}
+		}
+		break;
+
+		case AUDIO_S8: {
+			Sint8 *src, *dst;
+
+			src = (Sint8 *)cvt->buf;
+			dst = (Sint8 *)cvt->buf;
+			for ( i=cvt->len_cvt/4; i; --i ) {
+				dst[0] = src[0];
+				dst[1] = src[1];
+				src += 4;
+				dst += 2;
+			}
+		}
+		break;
+
+		case AUDIO_U16: {
+			Uint8 *src, *dst;
+
+			src = cvt->buf;
+			dst = cvt->buf;
+			if ( (format & 0x1000) == 0x1000 ) {
+				for ( i=cvt->len_cvt/8; i; --i ) {
+					lsample = (Uint16)((src[0]<<8)|src[1]);
+					rsample = (Uint16)((src[2]<<8)|src[3]);
+						dst[1] = (lsample&0xFF);
+						lsample >>= 8;
+						dst[0] = (lsample&0xFF);
+						dst[3] = (rsample&0xFF);
+						rsample >>= 8;
+						dst[2] = (rsample&0xFF);
+					src += 8;
+					dst += 4;
+				}
+			} else {
+				for ( i=cvt->len_cvt/8; i; --i ) {
+					lsample = (Uint16)((src[1]<<8)|src[0]);
+					rsample = (Uint16)((src[3]<<8)|src[2]);
+						dst[0] = (lsample&0xFF);
+						lsample >>= 8;
+						dst[1] = (lsample&0xFF);
+						dst[2] = (rsample&0xFF);
+						rsample >>= 8;
+						dst[3] = (rsample&0xFF);
+					src += 8;
+					dst += 4;
+				}
+			}
+		}
+		break;
+
+		case AUDIO_S16: {
+			Uint8 *src, *dst;
+
+			src = cvt->buf;
+			dst = cvt->buf;
+			if ( (format & 0x1000) == 0x1000 ) {
+				for ( i=cvt->len_cvt/8; i; --i ) {
+					lsample = (Sint16)((src[0]<<8)|src[1]);
+					rsample = (Sint16)((src[2]<<8)|src[3]);
+						dst[1] = (lsample&0xFF);
+						lsample >>= 8;
+						dst[0] = (lsample&0xFF);
+						dst[3] = (rsample&0xFF);
+						rsample >>= 8;
+						dst[2] = (rsample&0xFF);
+					src += 8;
+					dst += 4;
+				}
+			} else {
+				for ( i=cvt->len_cvt/8; i; --i ) {
+					lsample = (Sint16)((src[1]<<8)|src[0]);
+					rsample = (Sint16)((src[3]<<8)|src[2]);
+						dst[0] = (lsample&0xFF);
+						lsample >>= 8;
+						dst[1] = (lsample&0xFF);
+						dst[2] = (rsample&0xFF);
+						rsample >>= 8;
+						dst[3] = (rsample&0xFF);
+					src += 8;
+					dst += 4;
+				}
+			}
+		}
+		break;
+	}
+	cvt->len_cvt /= 2;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+/* Duplicate a mono channel to both stereo channels */
+void  SDL_ConvertStereo(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting to stereo\n");
+#endif
+	if ( (format & 0xFF) == 16 ) {
+		Uint16 *src, *dst;
+
+		src = (Uint16 *)(cvt->buf+cvt->len_cvt);
+		dst = (Uint16 *)(cvt->buf+cvt->len_cvt*2);
+		for ( i=cvt->len_cvt/2; i; --i ) {
+			dst -= 2;
+			src -= 1;
+			dst[0] = src[0];
+			dst[1] = src[0];
+		}
+	} else {
+		Uint8 *src, *dst;
+
+		src = cvt->buf+cvt->len_cvt;
+		dst = cvt->buf+cvt->len_cvt*2;
+		for ( i=cvt->len_cvt; i; --i ) {
+			dst -= 2;
+			src -= 1;
+			dst[0] = src[0];
+			dst[1] = src[0];
+		}
+	}
+	cvt->len_cvt *= 2;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+
+/* Duplicate a stereo channel to a pseudo-5.1 stream */
+void  SDL_ConvertSurround(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting stereo to surround\n");
+#endif
+	switch (format&0x8018) {
+
+		case AUDIO_U8: {
+			Uint8 *src, *dst, lf, rf, ce;
+
+			src = (Uint8 *)(cvt->buf+cvt->len_cvt);
+			dst = (Uint8 *)(cvt->buf+cvt->len_cvt*3);
+			for ( i=cvt->len_cvt; i; --i ) {
+				dst -= 6;
+				src -= 2;
+				lf = src[0];
+				rf = src[1];
+				ce = (lf/2) + (rf/2);
+				dst[0] = lf;
+				dst[1] = rf;
+				dst[2] = lf - ce;
+				dst[3] = rf - ce;
+				dst[4] = ce;
+				dst[5] = ce;
+			}
+		}
+		break;
+
+		case AUDIO_S8: {
+			Sint8 *src, *dst, lf, rf, ce;
+
+			src = (Sint8 *)cvt->buf+cvt->len_cvt;
+			dst = (Sint8 *)cvt->buf+cvt->len_cvt*3;
+			for ( i=cvt->len_cvt; i; --i ) {
+				dst -= 6;
+				src -= 2;
+				lf = src[0];
+				rf = src[1];
+				ce = (lf/2) + (rf/2);
+				dst[0] = lf;
+				dst[1] = rf;
+				dst[2] = lf - ce;
+				dst[3] = rf - ce;
+				dst[4] = ce;
+				dst[5] = ce;
+			}
+		}
+		break;
+
+		case AUDIO_U16: {
+			Uint8 *src, *dst;
+			Uint16 lf, rf, ce, lr, rr;
+
+			src = cvt->buf+cvt->len_cvt;
+			dst = cvt->buf+cvt->len_cvt*3;
+
+			if ( (format & 0x1000) == 0x1000 ) {
+				for ( i=cvt->len_cvt/4; i; --i ) {
+					dst -= 12;
+					src -= 4;
+					lf = (Uint16)((src[0]<<8)|src[1]);
+					rf = (Uint16)((src[2]<<8)|src[3]);
+					ce = (lf/2) + (rf/2);
+					rr = lf - ce;
+					lr = rf - ce;
+						dst[1] = (lf&0xFF);
+						dst[0] = ((lf>>8)&0xFF);
+						dst[3] = (rf&0xFF);
+						dst[2] = ((rf>>8)&0xFF);
+
+						dst[1+4] = (lr&0xFF);
+						dst[0+4] = ((lr>>8)&0xFF);
+						dst[3+4] = (rr&0xFF);
+						dst[2+4] = ((rr>>8)&0xFF);
+
+						dst[1+8] = (ce&0xFF);
+						dst[0+8] = ((ce>>8)&0xFF);
+						dst[3+8] = (ce&0xFF);
+						dst[2+8] = ((ce>>8)&0xFF);
+				}
+			} else {
+				for ( i=cvt->len_cvt/4; i; --i ) {
+					dst -= 12;
+					src -= 4;
+					lf = (Uint16)((src[1]<<8)|src[0]);
+					rf = (Uint16)((src[3]<<8)|src[2]);
+					ce = (lf/2) + (rf/2);
+					rr = lf - ce;
+					lr = rf - ce;
+						dst[0] = (lf&0xFF);
+						dst[1] = ((lf>>8)&0xFF);
+						dst[2] = (rf&0xFF);
+						dst[3] = ((rf>>8)&0xFF);
+
+						dst[0+4] = (lr&0xFF);
+						dst[1+4] = ((lr>>8)&0xFF);
+						dst[2+4] = (rr&0xFF);
+						dst[3+4] = ((rr>>8)&0xFF);
+
+						dst[0+8] = (ce&0xFF);
+						dst[1+8] = ((ce>>8)&0xFF);
+						dst[2+8] = (ce&0xFF);
+						dst[3+8] = ((ce>>8)&0xFF);
+				}
+			}
+		}
+		break;
+
+		case AUDIO_S16: {
+			Uint8 *src, *dst;
+			Sint16 lf, rf, ce, lr, rr;
+
+			src = cvt->buf+cvt->len_cvt;
+			dst = cvt->buf+cvt->len_cvt*3;
+
+			if ( (format & 0x1000) == 0x1000 ) {
+				for ( i=cvt->len_cvt/4; i; --i ) {
+					dst -= 12;
+					src -= 4;
+					lf = (Sint16)((src[0]<<8)|src[1]);
+					rf = (Sint16)((src[2]<<8)|src[3]);
+					ce = (lf/2) + (rf/2);
+					rr = lf - ce;
+					lr = rf - ce;
+						dst[1] = (lf&0xFF);
+						dst[0] = ((lf>>8)&0xFF);
+						dst[3] = (rf&0xFF);
+						dst[2] = ((rf>>8)&0xFF);
+
+						dst[1+4] = (lr&0xFF);
+						dst[0+4] = ((lr>>8)&0xFF);
+						dst[3+4] = (rr&0xFF);
+						dst[2+4] = ((rr>>8)&0xFF);
+
+						dst[1+8] = (ce&0xFF);
+						dst[0+8] = ((ce>>8)&0xFF);
+						dst[3+8] = (ce&0xFF);
+						dst[2+8] = ((ce>>8)&0xFF);
+				}
+			} else {
+				for ( i=cvt->len_cvt/4; i; --i ) {
+					dst -= 12;
+					src -= 4;
+					lf = (Sint16)((src[1]<<8)|src[0]);
+					rf = (Sint16)((src[3]<<8)|src[2]);
+					ce = (lf/2) + (rf/2);
+					rr = lf - ce;
+					lr = rf - ce;
+						dst[0] = (lf&0xFF);
+						dst[1] = ((lf>>8)&0xFF);
+						dst[2] = (rf&0xFF);
+						dst[3] = ((rf>>8)&0xFF);
+
+						dst[0+4] = (lr&0xFF);
+						dst[1+4] = ((lr>>8)&0xFF);
+						dst[2+4] = (rr&0xFF);
+						dst[3+4] = ((rr>>8)&0xFF);
+
+						dst[0+8] = (ce&0xFF);
+						dst[1+8] = ((ce>>8)&0xFF);
+						dst[2+8] = (ce&0xFF);
+						dst[3+8] = ((ce>>8)&0xFF);
+				}
+			}
+		}
+		break;
+	}
+	cvt->len_cvt *= 3;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+
+/* Duplicate a stereo channel to a pseudo-4.0 stream */
+void  SDL_ConvertSurround_4(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting stereo to quad\n");
+#endif
+	switch (format&0x8018) {
+
+		case AUDIO_U8: {
+			Uint8 *src, *dst, lf, rf, ce;
+
+			src = (Uint8 *)(cvt->buf+cvt->len_cvt);
+			dst = (Uint8 *)(cvt->buf+cvt->len_cvt*2);
+			for ( i=cvt->len_cvt; i; --i ) {
+				dst -= 4;
+				src -= 2;
+				lf = src[0];
+				rf = src[1];
+				ce = (lf/2) + (rf/2);
+				dst[0] = lf;
+				dst[1] = rf;
+				dst[2] = lf - ce;
+				dst[3] = rf - ce;
+			}
+		}
+		break;
+
+		case AUDIO_S8: {
+			Sint8 *src, *dst, lf, rf, ce;
+
+			src = (Sint8 *)cvt->buf+cvt->len_cvt;
+			dst = (Sint8 *)cvt->buf+cvt->len_cvt*2;
+			for ( i=cvt->len_cvt; i; --i ) {
+				dst -= 4;
+				src -= 2;
+				lf = src[0];
+				rf = src[1];
+				ce = (lf/2) + (rf/2);
+				dst[0] = lf;
+				dst[1] = rf;
+				dst[2] = lf - ce;
+				dst[3] = rf - ce;
+			}
+		}
+		break;
+
+		case AUDIO_U16: {
+			Uint8 *src, *dst;
+			Uint16 lf, rf, ce, lr, rr;
+
+			src = cvt->buf+cvt->len_cvt;
+			dst = cvt->buf+cvt->len_cvt*2;
+
+			if ( (format & 0x1000) == 0x1000 ) {
+				for ( i=cvt->len_cvt/4; i; --i ) {
+					dst -= 8;
+					src -= 4;
+					lf = (Uint16)((src[0]<<8)|src[1]);
+					rf = (Uint16)((src[2]<<8)|src[3]);
+					ce = (lf/2) + (rf/2);
+					rr = lf - ce;
+					lr = rf - ce;
+						dst[1] = (lf&0xFF);
+						dst[0] = ((lf>>8)&0xFF);
+						dst[3] = (rf&0xFF);
+						dst[2] = ((rf>>8)&0xFF);
+
+						dst[1+4] = (lr&0xFF);
+						dst[0+4] = ((lr>>8)&0xFF);
+						dst[3+4] = (rr&0xFF);
+						dst[2+4] = ((rr>>8)&0xFF);
+				}
+			} else {
+				for ( i=cvt->len_cvt/4; i; --i ) {
+					dst -= 8;
+					src -= 4;
+					lf = (Uint16)((src[1]<<8)|src[0]);
+					rf = (Uint16)((src[3]<<8)|src[2]);
+					ce = (lf/2) + (rf/2);
+					rr = lf - ce;
+					lr = rf - ce;
+						dst[0] = (lf&0xFF);
+						dst[1] = ((lf>>8)&0xFF);
+						dst[2] = (rf&0xFF);
+						dst[3] = ((rf>>8)&0xFF);
+
+						dst[0+4] = (lr&0xFF);
+						dst[1+4] = ((lr>>8)&0xFF);
+						dst[2+4] = (rr&0xFF);
+						dst[3+4] = ((rr>>8)&0xFF);
+				}
+			}
+		}
+		break;
+
+		case AUDIO_S16: {
+			Uint8 *src, *dst;
+			Sint16 lf, rf, ce, lr, rr;
+
+			src = cvt->buf+cvt->len_cvt;
+			dst = cvt->buf+cvt->len_cvt*2;
+
+			if ( (format & 0x1000) == 0x1000 ) {
+				for ( i=cvt->len_cvt/4; i; --i ) {
+					dst -= 8;
+					src -= 4;
+					lf = (Sint16)((src[0]<<8)|src[1]);
+					rf = (Sint16)((src[2]<<8)|src[3]);
+					ce = (lf/2) + (rf/2);
+					rr = lf - ce;
+					lr = rf - ce;
+						dst[1] = (lf&0xFF);
+						dst[0] = ((lf>>8)&0xFF);
+						dst[3] = (rf&0xFF);
+						dst[2] = ((rf>>8)&0xFF);
+
+						dst[1+4] = (lr&0xFF);
+						dst[0+4] = ((lr>>8)&0xFF);
+						dst[3+4] = (rr&0xFF);
+						dst[2+4] = ((rr>>8)&0xFF);
+				}
+			} else {
+				for ( i=cvt->len_cvt/4; i; --i ) {
+					dst -= 8;
+					src -= 4;
+					lf = (Sint16)((src[1]<<8)|src[0]);
+					rf = (Sint16)((src[3]<<8)|src[2]);
+					ce = (lf/2) + (rf/2);
+					rr = lf - ce;
+					lr = rf - ce;
+						dst[0] = (lf&0xFF);
+						dst[1] = ((lf>>8)&0xFF);
+						dst[2] = (rf&0xFF);
+						dst[3] = ((rf>>8)&0xFF);
+
+						dst[0+4] = (lr&0xFF);
+						dst[1+4] = ((lr>>8)&0xFF);
+						dst[2+4] = (rr&0xFF);
+						dst[3+4] = ((rr>>8)&0xFF);
+				}
+			}
+		}
+		break;
+	}
+	cvt->len_cvt *= 2;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+
+/* Convert 8-bit to 16-bit - LSB */
+void  SDL_Convert16LSB(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Uint8 *src, *dst;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting to 16-bit LSB\n");
+#endif
+	src = cvt->buf+cvt->len_cvt;
+	dst = cvt->buf+cvt->len_cvt*2;
+	for ( i=cvt->len_cvt; i; --i ) {
+		src -= 1;
+		dst -= 2;
+		dst[1] = *src;
+		dst[0] = 0;
+	}
+	format = ((format & ~0x0008) | AUDIO_U16LSB);
+	cvt->len_cvt *= 2;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+/* Convert 8-bit to 16-bit - MSB */
+void  SDL_Convert16MSB(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Uint8 *src, *dst;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting to 16-bit MSB\n");
+#endif
+	src = cvt->buf+cvt->len_cvt;
+	dst = cvt->buf+cvt->len_cvt*2;
+	for ( i=cvt->len_cvt; i; --i ) {
+		src -= 1;
+		dst -= 2;
+		dst[0] = *src;
+		dst[1] = 0;
+	}
+	format = ((format & ~0x0008) | AUDIO_U16MSB);
+	cvt->len_cvt *= 2;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+/* Convert 16-bit to 8-bit */
+void  SDL_Convert8(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Uint8 *src, *dst;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting to 8-bit\n");
+#endif
+	src = cvt->buf;
+	dst = cvt->buf;
+	if ( (format & 0x1000) != 0x1000 ) { /* Little endian */
+		++src;
+	}
+	for ( i=cvt->len_cvt/2; i; --i ) {
+		*dst = *src;
+		src += 2;
+		dst += 1;
+	}
+	format = ((format & ~0x9010) | AUDIO_U8);
+	cvt->len_cvt /= 2;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+/* Toggle signed/unsigned */
+void  SDL_ConvertSign(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Uint8 *data;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting audio signedness\n");
+#endif
+	data = cvt->buf;
+	if ( (format & 0xFF) == 16 ) {
+		if ( (format & 0x1000) != 0x1000 ) { /* Little endian */
+			++data;
+		}
+		for ( i=cvt->len_cvt/2; i; --i ) {
+			*data ^= 0x80;
+			data += 2;
+		}
+	} else {
+		for ( i=cvt->len_cvt; i; --i ) {
+			*data++ ^= 0x80;
+		}
+	}
+	format = (format ^ 0x8000);
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+/* Toggle endianness */
+void  SDL_ConvertEndian(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Uint8 *data, tmp;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting audio endianness\n");
+#endif
+	data = cvt->buf;
+	for ( i=cvt->len_cvt/2; i; --i ) {
+		tmp = data[0];
+		data[0] = data[1];
+		data[1] = tmp;
+		data += 2;
+	}
+	format = (format ^ 0x1000);
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+/* Convert rate up by multiple of 2 */
+void  SDL_RateMUL2(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Uint8 *src, *dst;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting audio rate * 2\n");
+#endif
+	src = cvt->buf+cvt->len_cvt;
+	dst = cvt->buf+cvt->len_cvt*2;
+	switch (format & 0xFF) {
+		case 8:
+			for ( i=cvt->len_cvt; i; --i ) {
+				src -= 1;
+				dst -= 2;
+				dst[0] = src[0];
+				dst[1] = src[0];
+			}
+			break;
+		case 16:
+			for ( i=cvt->len_cvt/2; i; --i ) {
+				src -= 2;
+				dst -= 4;
+				dst[0] = src[0];
+				dst[1] = src[1];
+				dst[2] = src[0];
+				dst[3] = src[1];
+			}
+			break;
+	}
+	cvt->len_cvt *= 2;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+
+/* Convert rate up by multiple of 2, for stereo */
+void  SDL_RateMUL2_c2(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Uint8 *src, *dst;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting audio rate * 2\n");
+#endif
+	src = cvt->buf+cvt->len_cvt;
+	dst = cvt->buf+cvt->len_cvt*2;
+	switch (format & 0xFF) {
+		case 8:
+			for ( i=cvt->len_cvt/2; i; --i ) {
+				src -= 2;
+				dst -= 4;
+				dst[0] = src[0];
+				dst[1] = src[1];
+				dst[2] = src[0];
+				dst[3] = src[1];
+			}
+			break;
+		case 16:
+			for ( i=cvt->len_cvt/4; i; --i ) {
+				src -= 4;
+				dst -= 8;
+				dst[0] = src[0];
+				dst[1] = src[1];
+				dst[2] = src[2];
+				dst[3] = src[3];
+				dst[4] = src[0];
+				dst[5] = src[1];
+				dst[6] = src[2];
+				dst[7] = src[3];
+			}
+			break;
+	}
+	cvt->len_cvt *= 2;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+/* Convert rate up by multiple of 2, for quad */
+void  SDL_RateMUL2_c4(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Uint8 *src, *dst;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting audio rate * 2\n");
+#endif
+	src = cvt->buf+cvt->len_cvt;
+	dst = cvt->buf+cvt->len_cvt*2;
+	switch (format & 0xFF) {
+		case 8:
+			for ( i=cvt->len_cvt/4; i; --i ) {
+				src -= 4;
+				dst -= 8;
+				dst[0] = src[0];
+				dst[1] = src[1];
+				dst[2] = src[2];
+				dst[3] = src[3];
+				dst[4] = src[0];
+				dst[5] = src[1];
+				dst[6] = src[2];
+				dst[7] = src[3];
+			}
+			break;
+		case 16:
+			for ( i=cvt->len_cvt/8; i; --i ) {
+				src -= 8;
+				dst -= 16;
+				dst[0] = src[0];
+				dst[1] = src[1];
+				dst[2] = src[2];
+				dst[3] = src[3];
+				dst[4] = src[4];
+				dst[5] = src[5];
+				dst[6] = src[6];
+				dst[7] = src[7];
+				dst[8] = src[0];
+				dst[9] = src[1];
+				dst[10] = src[2];
+				dst[11] = src[3];
+				dst[12] = src[4];
+				dst[13] = src[5];
+				dst[14] = src[6];
+				dst[15] = src[7];
+			}
+			break;
+	}
+	cvt->len_cvt *= 2;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+
+/* Convert rate up by multiple of 2, for 5.1 */
+void  SDL_RateMUL2_c6(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Uint8 *src, *dst;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting audio rate * 2\n");
+#endif
+	src = cvt->buf+cvt->len_cvt;
+	dst = cvt->buf+cvt->len_cvt*2;
+	switch (format & 0xFF) {
+		case 8:
+			for ( i=cvt->len_cvt/6; i; --i ) {
+				src -= 6;
+				dst -= 12;
+				dst[0] = src[0];
+				dst[1] = src[1];
+				dst[2] = src[2];
+				dst[3] = src[3];
+				dst[4] = src[4];
+				dst[5] = src[5];
+				dst[6] = src[0];
+				dst[7] = src[1];
+				dst[8] = src[2];
+				dst[9] = src[3];
+				dst[10] = src[4];
+				dst[11] = src[5];
+			}
+			break;
+		case 16:
+			for ( i=cvt->len_cvt/12; i; --i ) {
+				src -= 12;
+				dst -= 24;
+				dst[0] = src[0];
+				dst[1] = src[1];
+				dst[2] = src[2];
+				dst[3] = src[3];
+				dst[4] = src[4];
+				dst[5] = src[5];
+				dst[6] = src[6];
+				dst[7] = src[7];
+				dst[8] = src[8];
+				dst[9] = src[9];
+				dst[10] = src[10];
+				dst[11] = src[11];
+				dst[12] = src[0];
+				dst[13] = src[1];
+				dst[14] = src[2];
+				dst[15] = src[3];
+				dst[16] = src[4];
+				dst[17] = src[5];
+				dst[18] = src[6];
+				dst[19] = src[7];
+				dst[20] = src[8];
+				dst[21] = src[9];
+				dst[22] = src[10];
+				dst[23] = src[11];
+			}
+			break;
+	}
+	cvt->len_cvt *= 2;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+/* Convert rate down by multiple of 2 */
+void  SDL_RateDIV2(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Uint8 *src, *dst;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting audio rate / 2\n");
+#endif
+	src = cvt->buf;
+	dst = cvt->buf;
+	switch (format & 0xFF) {
+		case 8:
+			for ( i=cvt->len_cvt/2; i; --i ) {
+				dst[0] = src[0];
+				src += 2;
+				dst += 1;
+			}
+			break;
+		case 16:
+			for ( i=cvt->len_cvt/4; i; --i ) {
+				dst[0] = src[0];
+				dst[1] = src[1];
+				src += 4;
+				dst += 2;
+			}
+			break;
+	}
+	cvt->len_cvt /= 2;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+
+/* Convert rate down by multiple of 2, for stereo */
+void  SDL_RateDIV2_c2(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Uint8 *src, *dst;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting audio rate / 2\n");
+#endif
+	src = cvt->buf;
+	dst = cvt->buf;
+	switch (format & 0xFF) {
+		case 8:
+			for ( i=cvt->len_cvt/4; i; --i ) {
+				dst[0] = src[0];
+				dst[1] = src[1];
+				src += 4;
+				dst += 2;
+			}
+			break;
+		case 16:
+			for ( i=cvt->len_cvt/8; i; --i ) {
+				dst[0] = src[0];
+				dst[1] = src[1];
+				dst[2] = src[2];
+				dst[3] = src[3];
+				src += 8;
+				dst += 4;
+			}
+			break;
+	}
+	cvt->len_cvt /= 2;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+
+/* Convert rate down by multiple of 2, for quad */
+void  SDL_RateDIV2_c4(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Uint8 *src, *dst;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting audio rate / 2\n");
+#endif
+	src = cvt->buf;
+	dst = cvt->buf;
+	switch (format & 0xFF) {
+		case 8:
+			for ( i=cvt->len_cvt/8; i; --i ) {
+				dst[0] = src[0];
+				dst[1] = src[1];
+				dst[2] = src[2];
+				dst[3] = src[3];
+				src += 8;
+				dst += 4;
+			}
+			break;
+		case 16:
+			for ( i=cvt->len_cvt/16; i; --i ) {
+				dst[0] = src[0];
+				dst[1] = src[1];
+				dst[2] = src[2];
+				dst[3] = src[3];
+				dst[4] = src[4];
+				dst[5] = src[5];
+				dst[6] = src[6];
+				dst[7] = src[7];
+				src += 16;
+				dst += 8;
+			}
+			break;
+	}
+	cvt->len_cvt /= 2;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+/* Convert rate down by multiple of 2, for 5.1 */
+void  SDL_RateDIV2_c6(SDL_AudioCVT *cvt, Uint16 format)
+{
+	int i;
+	Uint8 *src, *dst;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting audio rate / 2\n");
+#endif
+	src = cvt->buf;
+	dst = cvt->buf;
+	switch (format & 0xFF) {
+		case 8:
+			for ( i=cvt->len_cvt/12; i; --i ) {
+				dst[0] = src[0];
+				dst[1] = src[1];
+				dst[2] = src[2];
+				dst[3] = src[3];
+				dst[4] = src[4];
+				dst[5] = src[5];
+				src += 12;
+				dst += 6;
+			}
+			break;
+		case 16:
+			for ( i=cvt->len_cvt/24; i; --i ) {
+				dst[0] = src[0];
+				dst[1] = src[1];
+				dst[2] = src[2];
+				dst[3] = src[3];
+				dst[4] = src[4];
+				dst[5] = src[5];
+				dst[6] = src[6];
+				dst[7] = src[7];
+				dst[8] = src[8];
+				dst[9] = src[9];
+				dst[10] = src[10];
+				dst[11] = src[11];
+				src += 24;
+				dst += 12;
+			}
+			break;
+	}
+	cvt->len_cvt /= 2;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+/* Very slow rate conversion routine */
+void  SDL_RateSLOW(SDL_AudioCVT *cvt, Uint16 format)
+{
+	double ipos;
+	int i, clen;
+
+#ifdef DEBUG_CONVERT
+	fprintf(stderr, "Converting audio rate * %4.4f\n", 1.0/cvt->rate_incr);
+#endif
+	clen = (int)((double)cvt->len_cvt / cvt->rate_incr);
+	if ( cvt->rate_incr > 1.0 ) {
+		switch (format & 0xFF) {
+			case 8: {
+				Uint8 *output;
+
+				output = cvt->buf;
+				ipos = 0.0;
+				for ( i=clen; i; --i ) {
+					*output = cvt->buf[(int)ipos];
+					ipos += cvt->rate_incr;
+					output += 1;
+				}
+			}
+			break;
+
+			case 16: {
+				Uint16 *output;
+
+				clen &= ~1;
+				output = (Uint16 *)cvt->buf;
+				ipos = 0.0;
+				for ( i=clen/2; i; --i ) {
+					*output=((Uint16 *)cvt->buf)[(int)ipos];
+					ipos += cvt->rate_incr;
+					output += 1;
+				}
+			}
+			break;
+		}
+	} else {
+		switch (format & 0xFF) {
+			case 8: {
+				Uint8 *output;
+
+				output = cvt->buf+clen;
+				ipos = (double)cvt->len_cvt;
+				for ( i=clen; i; --i ) {
+					ipos -= cvt->rate_incr;
+					output -= 1;
+					*output = cvt->buf[(int)ipos];
+				}
+			}
+			break;
+
+			case 16: {
+				Uint16 *output;
+
+				clen &= ~1;
+				output = (Uint16 *)(cvt->buf+clen);
+				ipos = (double)cvt->len_cvt/2;
+				for ( i=clen/2; i; --i ) {
+					ipos -= cvt->rate_incr;
+					output -= 1;
+					*output=((Uint16 *)cvt->buf)[(int)ipos];
+				}
+			}
+			break;
+		}
+	}
+	cvt->len_cvt = clen;
+	if ( cvt->filters[++cvt->filter_index] ) {
+		cvt->filters[cvt->filter_index](cvt, format);
+	}
+}
+
+int SDL_ConvertAudio(SDL_AudioCVT *cvt)
+{
+	/* Make sure there's data to convert */
+	if ( cvt->buf == NULL ) {
+		return(-1);
+	}
+	/* Return okay if no conversion is necessary */
+	cvt->len_cvt = cvt->len;
+	if ( cvt->filters[0] == NULL ) {
+		return(0);
+	}
+
+	/* Set up the conversion and go! */
+	cvt->filter_index = 0;
+	cvt->filters[0](cvt, cvt->src_format);
+	return(0);
+}
+
+/* Creates a set of audio filters to convert from one format to another.
+   Returns -1 if the format conversion is not supported, or 1 if the
+   audio filter is set up.
+*/
+
+int SDL_BuildAudioCVT(SDL_AudioCVT *cvt,
+	Uint16 src_format, Uint8 src_channels, int src_rate,
+	Uint16 dst_format, Uint8 dst_channels, int dst_rate)
+{
+/*printf("Build format %04x->%04x, channels %u->%u, rate %d->%d\n",
+		src_format, dst_format, src_channels, dst_channels, src_rate, dst_rate);*/
+	/* Start off with no conversion necessary */
+	cvt->needed = 0;
+	cvt->filter_index = 0;
+	cvt->filters[0] = NULL;
+	cvt->len_mult = 1;
+	cvt->len_ratio = 1.0;
+
+	/* First filter:  Endian conversion from src to dst */
+	if ( (src_format & 0x1000) != (dst_format & 0x1000)
+	     && ((src_format & 0xff) == 16) && ((dst_format & 0xff) == 16)) {
+		cvt->filters[cvt->filter_index++] = SDL_ConvertEndian;
+	}
+
+	/* Second filter: Sign conversion -- signed/unsigned */
+	if ( (src_format & 0x8000) != (dst_format & 0x8000) ) {
+		cvt->filters[cvt->filter_index++] = SDL_ConvertSign;
+	}
+
+	/* Next filter:  Convert 16 bit <--> 8 bit PCM */
+	if ( (src_format & 0xFF) != (dst_format & 0xFF) ) {
+		switch (dst_format&0x10FF) {
+			case AUDIO_U8:
+				cvt->filters[cvt->filter_index++] =
+							 SDL_Convert8;
+				cvt->len_ratio /= 2;
+				break;
+			case AUDIO_U16LSB:
+				cvt->filters[cvt->filter_index++] =
+							SDL_Convert16LSB;
+				cvt->len_mult *= 2;
+				cvt->len_ratio *= 2;
+				break;
+			case AUDIO_U16MSB:
+				cvt->filters[cvt->filter_index++] =
+							SDL_Convert16MSB;
+				cvt->len_mult *= 2;
+				cvt->len_ratio *= 2;
+				break;
+		}
+	}
+
+	/* Last filter:  Mono/Stereo conversion */
+	if ( src_channels != dst_channels ) {
+		if ( (src_channels == 1) && (dst_channels > 1) ) {
+			cvt->filters[cvt->filter_index++] =
+						SDL_ConvertStereo;
+			cvt->len_mult *= 2;
+			src_channels = 2;
+			cvt->len_ratio *= 2;
+		}
+		if ( (src_channels == 2) &&
+				(dst_channels == 6) ) {
+			cvt->filters[cvt->filter_index++] =
+						 SDL_ConvertSurround;
+			src_channels = 6;
+			cvt->len_mult *= 3;
+			cvt->len_ratio *= 3;
+		}
+		if ( (src_channels == 2) &&
+				(dst_channels == 4) ) {
+			cvt->filters[cvt->filter_index++] =
+						 SDL_ConvertSurround_4;
+			src_channels = 4;
+			cvt->len_mult *= 2;
+			cvt->len_ratio *= 2;
+		}
+		while ( (src_channels*2) <= dst_channels ) {
+			cvt->filters[cvt->filter_index++] =
+						SDL_ConvertStereo;
+			cvt->len_mult *= 2;
+			src_channels *= 2;
+			cvt->len_ratio *= 2;
+		}
+		if ( (src_channels == 6) &&
+				(dst_channels <= 2) ) {
+			cvt->filters[cvt->filter_index++] =
+						 SDL_ConvertStrip;
+			src_channels = 2;
+			cvt->len_ratio /= 3;
+		}
+		if ( (src_channels == 6) &&
+				(dst_channels == 4) ) {
+			cvt->filters[cvt->filter_index++] =
+						 SDL_ConvertStrip_2;
+			src_channels = 4;
+			cvt->len_ratio /= 2;
+		}
+		/* This assumes that 4 channel audio is in the format:
+		     Left {front/back} + Right {front/back}
+		   so converting to L/R stereo works properly.
+		 */
+		while ( ((src_channels%2) == 0) &&
+				((src_channels/2) >= dst_channels) ) {
+			cvt->filters[cvt->filter_index++] =
+						 SDL_ConvertMono;
+			src_channels /= 2;
+			cvt->len_ratio /= 2;
+		}
+		if ( src_channels != dst_channels ) {
+			/* Uh oh.. */;
+		}
+	}
+
+	/* Do rate conversion */
+	cvt->rate_incr = 0.0;
+	if ( (src_rate/100) != (dst_rate/100) ) {
+		Uint32 hi_rate, lo_rate;
+		int len_mult;
+		double len_ratio;
+		void ( *rate_cvt)(SDL_AudioCVT *cvt, Uint16 format);
+
+		if ( src_rate > dst_rate ) {
+			hi_rate = src_rate;
+			lo_rate = dst_rate;
+			switch (src_channels) {
+				case 1: rate_cvt = SDL_RateDIV2; break;
+				case 2: rate_cvt = SDL_RateDIV2_c2; break;
+				case 4: rate_cvt = SDL_RateDIV2_c4; break;
+				case 6: rate_cvt = SDL_RateDIV2_c6; break;
+				default: return -1;
+			}
+			len_mult = 1;
+			len_ratio = 0.5;
+		} else {
+			hi_rate = dst_rate;
+			lo_rate = src_rate;
+			switch (src_channels) {
+				case 1: rate_cvt = SDL_RateMUL2; break;
+				case 2: rate_cvt = SDL_RateMUL2_c2; break;
+				case 4: rate_cvt = SDL_RateMUL2_c4; break;
+				case 6: rate_cvt = SDL_RateMUL2_c6; break;
+				default: return -1;
+			}
+			len_mult = 2;
+			len_ratio = 2.0;
+		}
+		/* If hi_rate = lo_rate*2^x then conversion is easy */
+		while ( ((lo_rate*2)/100) <= (hi_rate/100) ) {
+			cvt->filters[cvt->filter_index++] = rate_cvt;
+			cvt->len_mult *= len_mult;
+			lo_rate *= 2;
+			cvt->len_ratio *= len_ratio;
+		}
+		/* We may need a slow conversion here to finish up */
+		if ( (lo_rate/100) != (hi_rate/100) ) {
+#if 1
+			/* The problem with this is that if the input buffer is
+			   say 1K, and the conversion rate is say 1.1, then the
+			   output buffer is 1.1K, which may not be an acceptable
+			   buffer size for the audio driver (not a power of 2)
+			*/
+			/* For now, punt and hope the rate distortion isn't great.
+			*/
+#else
+			if ( src_rate < dst_rate ) {
+				cvt->rate_incr = (double)lo_rate/hi_rate;
+				cvt->len_mult *= 2;
+				cvt->len_ratio /= cvt->rate_incr;
+			} else {
+				cvt->rate_incr = (double)hi_rate/lo_rate;
+				cvt->len_ratio *= cvt->rate_incr;
+			}
+			cvt->filters[cvt->filter_index++] = SDL_RateSLOW;
+#endif
+		}
+	}
+
+	/* Set up the filter information */
+	if ( cvt->filter_index != 0 ) {
+		cvt->needed = 1;
+		cvt->src_format = src_format;
+		cvt->dst_format = dst_format;
+		cvt->len = 0;
+		cvt->buf = NULL;
+		cvt->filters[cvt->filter_index] = NULL;
+	}
+	return(cvt->needed);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/src/SDL_audiocvt.hpp	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,49 @@
+#pragma once
+
+#ifndef _WINDOWS
+	#include <stdint.h>
+#else
+	typedef signed   __int8 int8_t;
+	typedef unsigned __int8 uint8_t;
+	typedef signed   __int16 int16_t;
+	typedef unsigned __int16 uint16_t;
+	typedef signed   __int32 int32_t;
+	typedef unsigned __int32 uint32_t;
+#endif
+
+#include <stdlib.h>
+/* Audio format flags (defaults to LSB byte order) */
+#define AUDIO_U8	0x0008	/* Unsigned 8-bit samples */
+#define AUDIO_S8	0x8008	/* Signed 8-bit samples */
+#define AUDIO_U16LSB	0x0010	/* Unsigned 16-bit samples */
+#define AUDIO_S16LSB	0x8010	/* Signed 16-bit samples */
+#define AUDIO_U16MSB	0x1010	/* As above, but big-endian byte order */
+#define AUDIO_S16MSB	0x9010	/* As above, but big-endian byte order */
+#define AUDIO_U16	AUDIO_U16LSB
+#define AUDIO_S16	AUDIO_S16LSB
+
+typedef int8_t		Sint8;
+typedef uint8_t		Uint8;
+typedef int16_t		Sint16;
+typedef uint16_t	Uint16;
+typedef int32_t		Sint32;
+typedef uint32_t	Uint32;
+
+/* A structure to hold a set of audio conversion filters and buffers */
+struct SDL_AudioCVT {
+	int needed;			/* Set to 1 if conversion possible */
+	Uint16 src_format;		/* Source audio format */
+	Uint16 dst_format;		/* Target audio format */
+	double rate_incr;		/* Rate conversion increment */
+	Uint8 *buf;			/* Buffer to hold entire audio data */
+	int    len;			/* Length of original audio buffer */
+	int    len_cvt;			/* Length of converted audio buffer */
+	int    len_mult;		/* buffer must be len*len_mult big */
+	double len_ratio; 	/* Given len, final size is len*len_ratio */
+	void (*filters[10])(struct SDL_AudioCVT *cvt, Uint16 format);
+	int filter_index;		/* Current audio conversion function */
+};
+int SDL_BuildAudioCVT(SDL_AudioCVT *cvt,
+	Uint16 src_format, Uint8 src_channels, int src_rate,
+	Uint16 dst_format, Uint8 dst_channels, int dst_rate);
+int SDL_ConvertAudio(SDL_AudioCVT *cvt);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/src/imp.hpp	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,122 @@
+#include <oggplayer.h>
+#include "SDL_audiocvt.hpp"
+#include <fstream>
+#include <vector>
+#include <theora/theora.h>
+#include <vorbis/codec.h>
+#include <boost/thread.hpp>
+#include <boost/bind.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/circular_buffer.hpp>
+#include <boost/timer.hpp>
+
+struct OggPlayer::Imp {
+
+	Imp() :
+		cirbuf(0),video_lock(video_mut, boost::defer_lock){
+		failbit = false;
+		playing = false;
+		need_close = false;
+		time_factor = 1;
+		refs = 1;
+	}
+
+	~Imp() {
+		// open() tears down the partial setup on fail
+		if (!failbit)
+			close();
+	}
+	int queue_page(ogg_page * page);
+	bool buffer_data();
+	double get_time();
+	void close();
+	bool init_decoders();
+	bool parse_headers();
+	void open(std::string path, AudioFormat audio_format, int channels,
+			int rate, VideoFormat video_format);
+	bool decode_audio();
+	bool decode_video();
+	bool ready();
+	void play();
+	void play_loop();
+
+	bool failbit;
+	std::ifstream file_in;
+
+	int theora_p;
+	int vorbis_p;
+
+	ogg_sync_state o_sync;
+
+	vorbis_comment v_comment;
+	theora_info t_info;
+	theora_comment t_comment;
+	vorbis_info v_info;
+
+	ogg_page o_page;
+	ogg_packet o_packet;
+
+	ogg_stream_state o_tsstate;
+	ogg_stream_state o_vsstate;
+
+	theora_state t_state;
+	vorbis_dsp_state v_state;
+	vorbis_block v_block;
+
+	int pp_level_max;
+	int pp_level;
+	int pp_inc;
+
+	char* audio_buffer;
+	boost::circular_buffer<char> cirbuf;
+	unsigned int audio_buffer_size;
+	SDL_AudioCVT cvt;
+
+	bool playing;
+
+	boost::thread play_thread;
+	boost::mutex audio_mut;
+	boost::mutex video_mut;
+	boost::condition_variable audio_ready_cond;
+	boost::condition_variable video_ready_cond;
+
+	bool videobuf_ready;
+	double videobuf_time;
+
+	bool audio_cache_ready;
+
+	// This lock should only be used from the main thread
+	boost::unique_lock<boost::mutex> video_lock;
+	// These variables are used to identify the frames (not just count them, not a debug variable)
+	// see video_buffer_try_lock and video_read
+	int frame;
+	int last_frame_read;
+
+	int audio_bytes_played;
+	struct AudioGranulePos {
+		int pos;
+		double set_time;
+	};
+	std::deque<AudioGranulePos> audio_granule_poses;
+	double time_factor;
+
+	struct PixelFormat{
+		void set(int r,int g,int b,int bpp){
+			r_offset = r;
+			g_offset = g;
+			b_offset = b;
+			this->bpp =bpp;
+		}
+		int r_offset;
+		int g_offset;
+		int b_offset;
+		// if bpp=4 we have an alpha channel at offset 4
+		int bpp;
+
+	} pixel_format;
+	bool need_close;
+	boost::timer timer;
+	int refs;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/src/oggplayer.cpp	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,180 @@
+#include <oggplayer.h>
+#include "imp.hpp"
+
+OggPlayer::~OggPlayer() {
+	imp->refs--;
+	if(imp->refs==0){
+		close();
+		delete imp;
+	}
+}
+
+OggPlayer::OggPlayer() {
+	imp = new Imp;
+}
+
+OggPlayer::OggPlayer(OggPlayer& os) {
+	imp = os.imp;
+	imp->refs++;
+}
+
+OggPlayer& OggPlayer::operator =(OggPlayer& os){
+	if(this==&os) return *this;
+	imp->refs--;
+	if(imp->refs==0){
+		close();
+		delete imp;
+	}
+	imp = os.imp;
+	imp->refs++;
+	return *this;
+}
+
+OggPlayer::OggPlayer(std::string path, AudioFormat audio_format, int channels,
+					 int rate, VideoFormat video_format){
+	imp = new Imp;
+	open(path, audio_format, channels, rate, video_format);
+}
+
+void OggPlayer::open(std::string path, AudioFormat audio_format, int channels,
+					 int rate, VideoFormat video_format) {
+	if(playing()) close();
+	imp->open(path, audio_format, channels, rate, video_format);
+}
+
+void OggPlayer::close() {
+	imp->playing = false;
+	// wait for play thread to terminate (if any)
+	imp->play_thread.join();
+}
+
+bool OggPlayer::fail() {
+	return imp->failbit;
+}
+
+void OggPlayer::play() {
+	imp->play();
+}
+
+bool OggPlayer::playing() {
+	return imp->playing;
+}
+
+
+int OggPlayer::audio_read(char* buf, unsigned int size) {
+	if(NULL==buf || !imp->vorbis_p || !playing() || !imp->ready()) return 0;
+	boost::unique_lock<boost::mutex> lock(imp->audio_mut);
+
+	while ((imp->cirbuf.size() < size) && playing()) {
+		if(imp->cirbuf.capacity()< size)
+		{
+			imp->cirbuf.set_capacity(2*size);
+		}
+		imp->audio_ready_cond.wait(lock);
+	}
+
+	unsigned int k = 0;
+	while (k < size && !imp->cirbuf.empty()) {
+		buf[k++] = imp->cirbuf.front();
+		imp->cirbuf.pop_front();
+	}
+	imp->audio_bytes_played+=k;
+
+	return k;
+}
+
+bool OggPlayer::yuv_buffer_try_lock(YUVBuffer *buffer) {
+	if (!playing() || !imp->theora_p || !imp->ready()) 
+		return false;
+	// no new data, no reason to lock
+	if(imp->last_frame_read==imp->frame)
+		return false;
+	imp->video_lock.lock();
+	while (!imp->videobuf_ready && playing()) {
+		imp->video_ready_cond.wait(imp->video_lock);
+	}
+	//ready and locked!
+	yuv_buffer yuv;
+	theora_decode_YUVout(&(imp->t_state), &yuv);
+
+	buffer->y_width = yuv.y_width;
+	buffer->y_height = yuv.y_height;
+	buffer->y_stride = yuv.y_stride;
+	buffer->uv_width = yuv.uv_width;
+	buffer->uv_height = yuv.uv_height;
+	buffer->uv_stride = yuv.uv_stride;
+	buffer->y = yuv.y;
+	buffer->u = yuv.u;
+	buffer->v = yuv.v;
+
+	imp->last_frame_read = imp->frame;
+	return true;
+}
+
+void OggPlayer::yuv_buffer_unlock() {
+	imp->video_lock.unlock();
+}
+
+inline int clamp(int val){
+	if(val<0) return 0;
+	if(val>255) return 255;
+	return val;
+}
+
+bool OggPlayer::video_read(char* buf, int stride) {
+	YUVBuffer yuv;
+	if(NULL==buf) return false;
+	if (!yuv_buffer_try_lock(&yuv))
+		return false;
+
+	if(0==stride) stride=width()*imp->pixel_format.bpp;
+	int h = height(), w = width();
+
+	int uv_ki=yuv.y_width/yuv.uv_width;
+	int uv_kj=yuv.y_height/yuv.uv_height;
+
+	int y_offset = offset_x() + yuv.y_stride * offset_y();
+	int uv_offset = offset_x()/uv_ki+yuv.uv_stride * offset_y()/uv_kj;
+	int y_p,uv_p,b_p;
+
+	for(int j=0;j<h;j++){
+		y_p=y_offset+j*yuv.y_stride;
+		b_p=j*stride;
+		uv_p=uv_offset+j/uv_kj*yuv.uv_stride;
+
+		for(int i=0;i<w;i++){
+			//http://en.wikipedia.org/wiki/YUV
+			int y = yuv.y[y_p]-16;
+			int u = yuv.u[uv_p]-128;
+			int v = yuv.v[uv_p]-128;
+			int r =clamp((y*298+409*v+128)>>8);
+			int g =clamp((y*298-100*v-208*u+128)>>8);
+			int b =clamp((y*298+516*u+128)>>8);
+			buf[b_p+imp->pixel_format.r_offset]=r;
+			buf[b_p+imp->pixel_format.g_offset]=g;
+			buf[b_p+imp->pixel_format.b_offset]=b;
+			if(4==imp->pixel_format.bpp)
+				buf[b_p+3]=255;
+
+			b_p+=imp->pixel_format.bpp;
+			y_p++;
+			if( i%uv_ki == uv_ki-1 ) uv_p++;
+		}
+	}
+	yuv_buffer_unlock();
+	return true;
+}
+
+int OggPlayer::width() {
+	return imp->t_info.width;
+}
+int OggPlayer::height() {
+	return imp->t_info.height;
+}
+int OggPlayer::offset_x() {
+	return imp->t_info.offset_x;
+}
+int OggPlayer::offset_y() {
+	return imp->t_info.offset_y;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/src/open_close.cpp	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,205 @@
+#include "imp.hpp"
+
+	void OggPlayer::Imp::close() {
+		if(!need_close) return;
+
+		if (vorbis_p) {
+			ogg_stream_clear(&o_vsstate);
+			vorbis_block_clear(&v_block);
+			vorbis_dsp_clear(&v_state);
+		}
+		vorbis_comment_clear(&v_comment);
+		vorbis_info_clear(&v_info);
+
+		if (theora_p) {
+			ogg_stream_clear(&o_tsstate);
+			theora_clear(&t_state);
+		}
+		theora_comment_clear(&t_comment);
+		theora_info_clear(&t_info);
+
+		ogg_sync_clear(&o_sync);
+		file_in.close();
+		if (audio_buffer){
+			delete[] audio_buffer;
+			audio_buffer = NULL;
+		}
+		need_close = false;
+	}
+	bool OggPlayer::Imp::parse_headers() {
+		int stateflag = 0;
+		while (!stateflag) {
+			if (!buffer_data())
+				break;
+			while (ogg_sync_pageout(&o_sync, &o_page) > 0) {
+				ogg_stream_state test;
+
+				/* is this a mandated initial header? If not, stop parsing */
+				if (!ogg_page_bos(&o_page)) {
+					/* don't leak the page; get it into the appropriate stream */
+					queue_page(&o_page);
+					stateflag = 1;
+					break;
+				}
+
+				ogg_stream_init(&test, ogg_page_serialno(&o_page));
+				ogg_stream_pagein(&test, &o_page);
+				ogg_stream_packetout(&test, &o_packet);
+
+				/* identify the codec: try theora */
+				if (!theora_p && theora_decode_header(&t_info, &t_comment,
+						&o_packet) >= 0) {
+					/* it is theora */
+					memcpy(&o_tsstate, &test, sizeof(test));
+					theora_p = 1;
+				} else if (!vorbis_p && vorbis_synthesis_headerin(&v_info,
+						&v_comment, &o_packet) >= 0) {
+					/* it is vorbis */
+					memcpy(&o_vsstate, &test, sizeof(test));
+					vorbis_p = 1;
+				} else {
+					/* whatever it is, we don't care about it */
+					ogg_stream_clear(&test);
+				}
+			}
+		}
+
+		// we're expecting more header packets.
+		while ((theora_p && theora_p < 3) || (vorbis_p && vorbis_p < 3)) {
+			int ret;
+
+			// look for further theora headers
+			while (theora_p && (theora_p < 3) && (ret = ogg_stream_packetout(
+					&o_tsstate, &o_packet))) {
+				if (ret < 0) {
+					return false;
+				}
+				if (theora_decode_header(&t_info, &t_comment, &o_packet)) {
+					return false;
+				}
+				theora_p++;
+			}
+
+			// look for more vorbis header packets
+			while (vorbis_p && (vorbis_p < 3) && (ret = ogg_stream_packetout(
+					&o_vsstate, &o_packet))) {
+				if (ret < 0) {
+					return false;
+				}
+				if (vorbis_synthesis_headerin(&v_info, &v_comment, &o_packet)) {
+					return false;
+				}
+				vorbis_p++;
+				if (vorbis_p == 3)
+					break;
+			}
+
+			// The header pages/packets will arrive before anything else we
+			//   care about, or the stream is not obeying spec
+
+			if (ogg_sync_pageout(&o_sync, &o_page) > 0) {
+				queue_page(&o_page); /* demux into the appropriate stream */
+			} else {
+				if (!buffer_data()) /* someone needs more data */{
+					return false;
+				}
+			}
+		}
+		return true;
+
+	}
+
+	bool OggPlayer::Imp::init_decoders() {
+		if (theora_p) {
+			theora_decode_init(&t_state, &t_info);
+			theora_control(&t_state, TH_DECCTL_GET_PPLEVEL_MAX, &pp_level_max,
+					sizeof(pp_level_max));
+			pp_level = pp_level_max;
+			theora_control(&t_state, TH_DECCTL_SET_PPLEVEL, &pp_level,
+					sizeof(pp_level));
+			pp_inc = 0;
+		} else {
+			return false;
+		}
+		if (vorbis_p) {
+			vorbis_synthesis_init(&v_state, &v_info);
+			vorbis_block_init(&v_state, &v_block);
+		} else {
+			return false;
+		}
+		return true;
+	}
+
+	void OggPlayer::Imp::open(std::string path, AudioFormat audio_format, int channels,
+			int rate, VideoFormat video_format) {
+				
+		theora_p = 0;
+		vorbis_p = 0;
+		videobuf_ready = false;
+		frame=0;
+		last_frame_read=0;
+
+		// 1) open the input file
+		file_in.open(path.c_str(), std::ios::binary);
+		if (file_in.fail()) {
+			failbit = true;
+			return;
+		}
+
+		// 2) init some structs
+		ogg_sync_init(&o_sync);
+		vorbis_info_init(&v_info);
+		vorbis_comment_init(&v_comment);
+		theora_info_init(&t_info);
+		theora_comment_init(&t_comment);
+
+		// 3) parse headers
+		if (!failbit && !parse_headers()) {
+			failbit = true;
+		}
+
+		// 3) init decoders
+		if (!failbit && !init_decoders()) {
+			failbit = true;
+		}
+
+		// 4) if fail, tear down the partial setup
+		if (failbit) {
+			theora_info_clear(&t_info);
+			theora_comment_clear(&t_comment);
+			vorbis_info_clear(&v_info);
+			vorbis_comment_clear(&v_comment);
+			ogg_sync_clear(&o_sync);
+			file_in.close();
+			return;
+		}
+
+		// 5) init audio conversion
+		int ret = SDL_BuildAudioCVT(&cvt, AUDIO_S16, v_info.channels,
+				v_info.rate, audio_format, channels, rate);
+		if (-1 == ret) {
+			failbit = true;
+			return;
+		}
+		// play() will allocate memory when needed
+		audio_buffer_size = 0;
+		audio_buffer = NULL;
+
+		switch(video_format){
+		//pixel_format.set(r_offset,g_offset,b_offset,bpp not a_offset);
+		case VF_RGB:
+			pixel_format.set(0,1,2,3);
+			break;
+		case VF_BGR:
+			pixel_format.set(2,1,0,3);
+			break;
+		case VF_RGBA:
+			pixel_format.set(0,1,2,4);
+			break;
+		case VF_BGRA:
+			pixel_format.set(2,1,0,4);
+			break;
+		}
+		need_close = true;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/src/play.cpp	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,184 @@
+#include "imp.hpp"
+
+bool OggPlayer::Imp::ready() {
+	return audio_cache_ready;
+}
+// return true if need more data
+// the return value is strange but the function is
+// for internal use only and should only be called
+// in play()
+bool OggPlayer::Imp::decode_audio() {
+	int ret;
+	float **pcm;
+	// if there's pending, decoded audio, grab it
+	while ((ret = vorbis_synthesis_pcmout(&v_state, &pcm)) > 0) {
+		boost::unique_lock<boost::mutex> lock(audio_mut);
+		// first we need to convert from float to signed short
+		// then we will use SDL_ConvertAudio
+		// is our temp buffer big enough?
+		if (cirbuf.capacity() < ret * v_info.channels * cvt.len_mult
+			* sizeof(short)) {
+				cirbuf.set_capacity(ret * v_info.channels * cvt.len_mult * 16
+					* sizeof(short));
+		}
+		if (cirbuf.capacity() - cirbuf.size() < ret * v_info.channels
+			* cvt.len_mult * sizeof(short)) {
+				audio_cache_ready = true;
+				return false;
+		}
+		if ((audio_buffer_size) < ret * v_info.channels * cvt.len_mult
+			* sizeof(short)) {
+				if (audio_buffer)
+					delete[] audio_buffer;
+				audio_buffer_size = ret * v_info.channels * cvt.len_mult
+					* sizeof(short);
+				audio_buffer = new char[audio_buffer_size];
+		}
+		// convert from float to short
+		int k = 0;
+		char* char_ab = (char*) audio_buffer;
+		short* short_ab = (short*) audio_buffer;
+		for (int i = 0; i < ret; i++) {
+			for (int j = 0; j < v_info.channels; j++) {
+				int val = (int)(pcm[j][i] * 32767.f);
+				if (val > 32767)
+					val = 32767;
+				if (val < -32768)
+					val = -32768;
+				short_ab[k++] = val;
+
+			}
+		}
+		vorbis_synthesis_read(&v_state, ret);
+		// now we can use SDL_ConvertAudio
+		cvt.len = k * sizeof(short);
+		cvt.buf = (Uint8*) char_ab;
+		SDL_ConvertAudio(&cvt);
+
+		for (int i = 0; i < cvt.len_cvt; i++) {
+			cirbuf.push_back(char_ab[i]);
+		}
+
+
+		if(v_state.granulepos!=0){
+			AudioGranulePos agp;
+			agp.pos = audio_bytes_played+cvt.len_cvt;
+			agp.set_time = (double)v_state.granulepos/(double)v_info.rate;
+			audio_granule_poses.push_back(agp);
+		}
+
+		lock.unlock();
+		audio_ready_cond.notify_one();
+		return false;
+
+	} 
+	// no pending audio; is there a pending packet to decode?
+	if (ogg_stream_packetout(&o_vsstate, &o_packet) > 0) {
+		if (vorbis_synthesis(&v_block, &o_packet) == 0) {
+			vorbis_synthesis_blockin(&v_state, &v_block);
+			return false;
+		}
+	} else { return true; }
+
+}
+// similar to decode_audio
+bool OggPlayer::Imp::decode_video() {
+	bool was_ready=videobuf_ready;
+	boost::unique_lock<boost::mutex> lock(video_mut, boost::defer_lock);
+	ogg_int64_t videobuf_granulepos = -1;
+	if (!videobuf_ready){
+		if(!lock.try_lock())
+			return false;
+	}
+	while (!videobuf_ready) {
+		// theora is one in, one out...
+		if (ogg_stream_packetout(&o_tsstate, &o_packet) > 0) {
+
+			if(pp_inc){
+				pp_level+=pp_inc;
+				theora_control(&t_state,TH_DECCTL_SET_PPLEVEL,&pp_level,sizeof(pp_level));
+				pp_inc=0;
+			}
+			if (o_packet.granulepos >= 0) {
+				theora_control(&t_state, TH_DECCTL_SET_GRANPOS,
+					&o_packet.granulepos, sizeof(o_packet.granulepos));
+			}
+			if (theora_decode_packetin(&t_state, &o_packet) == 0) {
+				videobuf_granulepos = t_state.granulepos;
+				videobuf_time = theora_granule_time(&t_state,	videobuf_granulepos);
+
+				if (videobuf_time >= get_time()){
+					videobuf_ready = true;
+					frame++;
+				}
+				else {
+					// If we are too slow, reduce the pp level.
+					pp_inc=pp_level>0?-1:0;
+				}
+			}
+
+		} else
+			break;
+	}
+	lock.unlock();
+	if(videobuf_ready!=was_ready)
+		video_ready_cond.notify_one();
+
+	return !videobuf_ready;
+}
+
+void OggPlayer::Imp::play_loop() {
+	if(!file_in.is_open()) return;
+	audio_cache_ready = false;
+	audio_bytes_played = 0;
+	bool audio_need_data = vorbis_p;
+	bool video_need_data = theora_p;
+	timer.restart();
+	// buffer_data() will close the file on eof
+	while ((file_in.is_open() || !audio_need_data || !video_need_data) && playing) {
+
+		// sync audio video timer
+		while(!audio_granule_poses.empty() &&
+			audio_granule_poses.front().pos <= audio_bytes_played){
+			time_factor= audio_granule_poses.front().set_time/timer.elapsed();
+			audio_granule_poses.pop_front();
+		}
+
+		if (theora_p && !videobuf_ready) {
+			video_need_data = decode_video();
+		}
+
+		if (vorbis_p) {
+			audio_need_data = decode_audio();
+		}
+
+		// are we at or past time for this video frame?
+		if (videobuf_ready && videobuf_time <= get_time()) {
+			videobuf_ready = false;
+		}
+		// if no data yet for somebody, grab another page
+		if (file_in.is_open() && (audio_need_data || video_need_data)) {
+			// buffer_data() can handle eof itself
+			buffer_data();
+			while (ogg_sync_pageout(&o_sync, &o_page) > 0) {
+				queue_page(&o_page);
+			}
+			audio_need_data = false;
+			video_need_data = false;
+		}
+	}
+	playing = false;
+
+	// do not risk a lock
+	audio_ready_cond.notify_one();
+	video_ready_cond.notify_one();
+
+	// cleanup
+	close();
+}
+
+void OggPlayer::Imp::play() {
+	playing = true;
+	play_thread = boost::thread(boost::bind(&OggPlayer::Imp::play_loop, this));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/src/readme.txt	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,1 @@
+This library includes some modified files from SDL (http://www.libsdl.org/).
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboggplayer-src/src/util.cpp	Mon Aug 05 13:50:20 2013 +0300
@@ -0,0 +1,30 @@
+#include "imp.hpp"
+#ifdef _WINDOWS
+#include <windows.h>
+#endif
+int OggPlayer::Imp::queue_page(ogg_page * page) {
+	if (theora_p)
+		ogg_stream_pagein(&o_tsstate, page);
+	if (vorbis_p)
+		ogg_stream_pagein(&o_vsstate, page);
+	return 0;
+}
+
+bool OggPlayer::Imp::buffer_data() {
+	if (!file_in.is_open())
+		return 0;
+	if (file_in.eof()) {
+		file_in.close();
+		return 0;
+	}
+	char *buffer = ogg_sync_buffer(&o_sync, 4096);
+	int bytes = file_in.read(buffer, 4096).gcount();
+	ogg_sync_wrote(&o_sync, bytes);
+	return (bytes != 0);
+}
+
+double OggPlayer::Imp::get_time() {
+	double now = time_factor*timer.elapsed();
+	return now;
+}
+