[xiph-commits] r3873 - in liboggplay/trunk: src/examples win32

wiking at svn.annodex.net wiking at svn.annodex.net
Tue Mar 3 17:40:34 PST 2009


Author: wiking
Date: 2009-03-03 17:40:33 -0800 (Tue, 03 Mar 2009)
New Revision: 3873

Modified:
   liboggplay/trunk/src/examples/win32-player.c
   liboggplay/trunk/win32/config_win32.h
Log:
- Fixed Ticket #443: changed the deprecated functions in example player for Windows.
- update config_win32.h macros. a macro defined with 0 value does not mean that it is not define, indeed an #ifdef will be true.

Modified: liboggplay/trunk/src/examples/win32-player.c
===================================================================
--- liboggplay/trunk/src/examples/win32-player.c	2009-03-03 14:22:48 UTC (rev 3872)
+++ liboggplay/trunk/src/examples/win32-player.c	2009-03-04 01:40:33 UTC (rev 3873)
@@ -1,851 +1,844 @@
-#include "config_win32.h"
-
-#include <oggplay/oggplay.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <windows.h>
-
-#define OPENGL 0
-
-#if OPENGL
-#include <glut.h> // requires OpenGL for Win32
-#endif /* !OPENGL */
-
-#define USE_AUDIO 1
-
-#if USE_AUDIO
-#include <mmreg.h>
-#include <math.h>
-#endif
-
-#include <assert.h>
-
-static int            n_frames = 0;
-static DWORD			    position = 0;
-static UINT				    target = 0;
-static DWORD          rate = 0;
-static UINT				    channels = 2;
-static BOOL				    buffering = TRUE;
-static BOOL				    audio_opened = FALSE;
-
-static UINT          total_bytes = 0;
-
-#if OPENGL
-static GLuint texture;
-#endif
-
-#define OGGPLAY_BUFFER_SIZE 20
-#define BLOCK_SIZE  2560
-#define BLOCK_COUNT 4
-
-static unsigned char  *texture_bits = NULL;
-static int            texture_width;
-static int            texture_height;
-static float          texture_wscale;
-static float          texture_hscale;
-static int            window_width;
-static int            window_height;
-static int            window_style;
-
-static OggPlay*       player = NULL;
-
-static CRITICAL_SECTION waveCriticalSection;
-static HWAVEOUT			    hWaveOut;
-static WAVEHDR*         waveBlocks = NULL;
-static volatile int     waveFreeBlockCount;
-static int              waveCurrentBlock;
-
-static HANDLE			      audio_synch;
-typedef struct {
-  HANDLE           decode_thread;
-  HANDLE           display_thread;
-} Player_Info;
-
-
-// oggplay buffer underrun semaphore
-static HANDLE           sem;
-static HWAVEOUT         audio_dev;
-
-static int video_track;
-static int audio_track;
-
-
-#define APPLICATIONNAME TEXT("OggPlay Media Player\0")
-#define CLASSNAME       TEXT("OggPlayMediaPlayer\0")
-
-#if OPENGL
-static int        window;
-#else
-static HWND        window;
-#endif /*OPENGL*/
-
-#define DISPLAY_FRAMES 1
-
-#define CLAMP(v) (v > 255 ? 255 : v < 0 ? 0 : v)
-
-
-void
-handle_video_data (OggPlay * player, int track_num, 
-                    OggPlayVideoData * video_data, int frame) {
-
-  int               i;      
-  int               y_width;
-  int               y_height;
-  int               uv_width;
-  int               uv_height;
-  int               po2_width;
-  int               po2_height;  
-  int				style;
-  OggPlayYUVChannels      yuv;
-  OggPlayRGBChannels      rgb;  
-  RECT				r;
-
-#if 0  
-  unsigned char*     ptry;
-  unsigned char*     ptru;
-  unsigned char*     ptrv;
-  unsigned char*     ptro;
-  unsigned char*     ptro2;
-#endif
-
-  oggplay_get_video_y_size(player, track_num, &y_width, &y_height);
-  if (y_width != window_width)
-  {
-#if DISPLAY_FRAMES
-#if OPENGL
-	glutReshapeWindow(y_width, y_height);
-#else    
-    style = window_style & ~ WS_OVERLAPPED;
-    GetClientRect(window, &r);
-	r.right = r.left + y_width + 5;
-	r.bottom = r.top + y_height + 5;
-	// allow for the border, title size, etc.
-	AdjustWindowRect(&r, style, FALSE);
-	SetWindowPos(window, HWND_TOP, 0, 0, 
-        r.right - r.left, r.bottom - r.top,
-		SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOMOVE | 
-		SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOZORDER | SWP_SHOWWINDOW);
-	UpdateWindow(window);
-#endif /* !OPENGL */
-#endif;
-    window_width = y_width;
-    window_height = y_height;
-  }
-    
-  oggplay_get_video_uv_size(player, track_num, &uv_width, &uv_height);
-  assert(uv_width == y_width / 2);
-  assert(uv_height == y_height / 2);
-  
-  for (po2_width = 1; po2_width < y_width; po2_width <<= 1);
-  for (po2_height = 1; po2_height < y_height; po2_height <<= 1);
-  texture_wscale = (float) y_width / po2_width;
-  texture_hscale = (float) y_height / po2_height;
-
-  if (texture_bits == NULL) {
-
-    texture_bits = (unsigned char*)calloc(1, po2_width * po2_height * 4);
-    texture_width = po2_width;
-    texture_height = po2_height;    
-    
-  } else if (texture_width != po2_width || texture_height != po2_height) {
-
-    free(texture_bits);
-    
-    texture_bits = (unsigned char*)calloc(1, po2_width * po2_height * 4);
-    texture_width = po2_width;
-    texture_height = po2_height;
-  }
-
-  /*
-   *  R = Y + 1.140V
-   *  G = Y - 0.395U - 0.581V
-   *  B = Y + 2.032U
-   */
-    
-#if 1
-  
-  yuv.ptry = video_data->y;
-  yuv.ptru = video_data->u;
-  yuv.ptrv = video_data->v;
-  yuv.uv_width = uv_width;
-  yuv.uv_height = uv_height;  
-  yuv.y_width = y_width;
-  yuv.y_height = y_height;  
-  
-  rgb.ptro = texture_bits;
-  rgb.rgb_width = texture_width;
-  rgb.rgb_height = texture_height;  
-
-#if OPENGL
-  oggplay_yuv2rgba(&yuv, &rgb);
-#else
-  oggplay_yuv2bgra(&yuv, &rgb);
-#endif 
-  
-#endif
- 
-}
-
-#if USE_AUDIO
-
-void
-float_to_short_array(const float* in, short* out, int len) {
-        int i = 0;
-        float scaled_value = 0;		
-        for(i = 0; i < len; i++) {				
-                scaled_value = floorf(0.5 + 32768 * in[i]);
-                if (in[i] < 0) {
-                   out[i] = (scaled_value < -32768.0) ? -32768 : (short)scaled_value;
-                } else {
-                   out[i] = (scaled_value > 32767.0) ? 32767 : (short)scaled_value;
-                }
-        }
-}
-
-WAVEHDR* allocateBlocks(int size, int count)
-{
-    unsigned char* buffer;    
-    int i;
-    WAVEHDR* blocks;
-    DWORD totalBufferSize = (size + sizeof(WAVEHDR)) * count;
-    
-    /*
-     * allocate memory for the entire set in one go     
-     */    
-    if((buffer = HeapAlloc(
-        GetProcessHeap(), 
-        HEAP_ZERO_MEMORY, 
-        totalBufferSize
-        )) == NULL) {
-        printf("Memory allocation error\n");
-        ExitProcess(1);
-    }
-
-    /*
-     * and set up the pointers to each bit
-     */
-    blocks = (WAVEHDR*)buffer;
-    buffer += sizeof(WAVEHDR) * count;
-    for(i = 0; i < count; i++) {
-        blocks[i].dwBufferLength = size;
-        blocks[i].lpData = buffer;
-        buffer += size;
-    }
-    
-    return blocks;
-}
-
-void freeBlocks(WAVEHDR* blockArray)
-{    
-	  /* 
-     * and this is why allocateBlocks works the way it does     
-     */     
-    HeapFree(GetProcessHeap(), 0, blockArray);
-}
-
-static void CALLBACK waveOutProc(
-    HWAVEOUT hWaveOut, 
-    UINT uMsg, 
-    DWORD dwInstance,  
-    DWORD dwParam1,    
-    DWORD dwParam2     
-)
-{
-    /*
-     * pointer to free block counter
-     */
-    int* freeBlockCounter = (int*)dwInstance;
-    /*
-     * ignore calls that occur due to openining and closing the
-     * device.
-     */
-    if(uMsg != WOM_DONE)
-        return;
-
-    EnterCriticalSection(&waveCriticalSection);
-    (*freeBlockCounter)++;
-    /*if ((*freeBlockCounter) == 1) 
-       SetEvent(audio_synch);*/
-    LeaveCriticalSection(&waveCriticalSection);	
-}
-
-void openAudio(OggPlay * player, int track) {
-	WAVEFORMATEX wfx;		
-	UINT fps = 25; // get from the stream information
-	UINT supported = FALSE;
-		
-	waveBlocks         = allocateBlocks(BLOCK_SIZE, BLOCK_COUNT);
-	waveFreeBlockCount = BLOCK_COUNT;
-  waveCurrentBlock   = 0;  
- 	wfx.nSamplesPerSec  = (DWORD)rate;  /* sample rate */
-  wfx.wBitsPerSample  = 16;     /* sample size */
-  wfx.nChannels       = channels;      /* channels    */
-  wfx.cbSize          = 0;      /* size of _extra_ info */
-  wfx.wFormatTag      = WAVE_FORMAT_PCM;
-  wfx.nBlockAlign     = (wfx.wBitsPerSample * wfx.nChannels) >> 3;
-  wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
-	// target sample size in bytes for each frame
-	target				= wfx.nAvgBytesPerSec / fps; 	
-
-	supported = waveOutOpen(NULL, WAVE_MAPPER, &wfx, (DWORD_PTR)0, (DWORD_PTR)0, 
-		WAVE_FORMAT_QUERY);
-	if (supported == MMSYSERR_NOERROR) { // audio device sucessfully opened
-		waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER, &wfx, 
-	      (DWORD_PTR)waveOutProc, (DWORD_PTR)&waveFreeBlockCount, CALLBACK_FUNCTION);
-		//printf("Audio device sucessfully opened\n");
-	} else if (supported == WAVERR_BADFORMAT) {
-       printf("Requested format not supported...\n");
-       ExitProcess(1);
-	} else {
-       printf("Error opening default audio device. Exiting...\n");
-       ExitProcess(1);
-	}	
-  return;
-}
-
-
-void writeAudio(LPSTR data, int samples)
-{    
-	WAVEHDR* current;	
-  int bytes;
-	int remain;
-
-  current = &waveBlocks[waveCurrentBlock];
-  
-  while(samples > 0) {
-      /* 
-       * first make sure the header we're going to use is unprepared
-       */
-      if(current->dwFlags & WHDR_PREPARED) 
-          waveOutUnprepareHeader(hWaveOut, current, sizeof(WAVEHDR));
-	
-	    bytes = sizeof(short) * samples;
-      total_bytes += bytes;
-      if(bytes < (int)(BLOCK_SIZE - current->dwUser)) {						
-	  	    float_to_short_array((float*)data, (short*)(current->lpData + current->dwUser), samples);						
-		      //memcpy(current->lpData + current->dwUser, data, size);
-          current->dwUser += bytes;
-          break;
-      }
-	
-      // bytes is even as BLOCK_SIZE and dwUser are even too
-      bytes = BLOCK_SIZE - current->dwUser;
-	    remain = bytes / sizeof(short); // samples left in the buffer		
-      float_to_short_array((float*)data, (short*)(current->lpData + current->dwUser), remain);
-  		//memcpy(current->lpData + current->dwUser, data, remain);
-      samples -= remain;
-      data += 2 * bytes;		
-	    current->dwBufferLength = BLOCK_SIZE;
-	    waveOutPrepareHeader(hWaveOut, current, sizeof(WAVEHDR));
-	    waveOutWrite(hWaveOut, current, sizeof(WAVEHDR));
-      if (buffering == TRUE) {
-        printf("Total bytes %d\n", total_bytes);
-      }
-      buffering = FALSE;		
-      
-      EnterCriticalSection(&waveCriticalSection);
-      waveFreeBlockCount--;
-      LeaveCriticalSection(&waveCriticalSection);
-      /*
-       * wait for a block to become free
-       */
-      while (!waveFreeBlockCount) {        
-        //printf("All audio buffer blocks empty\n");        
-        //WaitForSingleObject(audio_synch, INFINITE);
-        Sleep(10);
-      }		  
-		
-      /*
-       * point to the next block
-       */
-      waveCurrentBlock++;
-      waveCurrentBlock %= BLOCK_COUNT;		
-
-      current = &waveBlocks[waveCurrentBlock];
-      current->dwUser = 0;
-  }
-}
-
-void 
-closeAudio() {
-  int i;
-  /*
-   * wait for all blocks to complete
-   */
-  while(waveFreeBlockCount < BLOCK_COUNT)
-	  Sleep(10);
-
- /*
-  * unprepare any blocks that are still prepared
-  */
-  for(i = 0; i < waveFreeBlockCount; i++) 
-    if(waveBlocks[i].dwFlags & WHDR_PREPARED)
-	  waveOutUnprepareHeader(hWaveOut, &waveBlocks[i], sizeof(WAVEHDR));
-
-  freeBlocks(waveBlocks);
-  waveOutClose(hWaveOut);
-    
-}
-
-void
-handle_audio_data (OggPlay * player, int track, OggPlayAudioData * data, 
-                int size) {		
-	if (audio_opened == FALSE) {
-		openAudio(player, track);
-		audio_opened = TRUE;
-
-	}
-	writeAudio((LPSTR)data, size);  
-}
-#endif
-
-#if !OPENGL
-DWORD WINAPI display_frame(void *arg) {
-#else 
-void display_frame(void) {
-#endif
-  int                     i;
-  int                     j;
-  OggPlayDataHeader    ** headers;
-  OggPlayVideoData      * video_data;
-#if USE_AUDIO
-  OggPlayAudioData      * audio_data;
-#endif
-  int					  size;
-  int                     required;
-  OggPlayDataType         type;
-  int                     num_tracks;
-  OggPlayCallbackInfo  ** track_info;  
-  DWORD				            offset = 0;  
-  DWORD                   delay;
-  MMTIME                  mm;
-
-  delay = 40; // 40ms timeslots @ 25 fps
-
-  num_tracks = oggplay_get_num_tracks (player);
-
-  //nice(5);
-
-#if !OPENGL
-  while (1) { 
-#endif
-    track_info = oggplay_buffer_retrieve_next(player);
-    if (track_info == NULL) {
-#if DISPLAY_FRAMES
-      Sleep(delay);      
-
-#if OPENGL            
-      return;
-#else
-      continue;
-#endif
-    }
-#endif
-    // make sure the playback rate is correct
-	  if (buffering == FALSE) {		
-		  mm.wType = TIME_BYTES;		
-		  waveOutGetPosition(hWaveOut, &mm, sizeof(MMTIME));						  
-      if (target > (DWORD)mm.u.cb - position) {						  
-        offset = (target - (DWORD)mm.u.cb + position) * delay / target;												                               
-        Sleep(offset);
-		  }      
-		  position = (DWORD)mm.u.cb;
-	  }
-    for (i = 0; i < num_tracks; i++) {
-      type = oggplay_callback_info_get_type(track_info[i]);
-      headers = oggplay_callback_info_get_headers(track_info[i]);
-    
-      switch (type) {
-        case OGGPLAY_INACTIVE:
-          break;
-        case OGGPLAY_YUV_VIDEO:
-          /*
-           * there should only be one record
-           */
-          required = oggplay_callback_info_get_required(track_info[i]);
-          if (required == 0) {
-            oggplay_buffer_free_info(track_info);
-            oggplay_buffer_release_next(player);            
-            goto next_frame;
-            }
-          video_data = oggplay_callback_info_get_video_data(headers[0]);
-          //printf("video presentation time: %llx\n",
-          //        oggplay_callback_info_get_presentation_time(headers[0]));
-          handle_video_data(player, i, video_data, n_frames);
-          break;
-        case OGGPLAY_FLOATS_AUDIO:
-#if USE_AUDIO
-          required = oggplay_callback_info_get_required(track_info[i]);          
-          // fill in fist and second buffer          
-          for (j = 0; j < required; j++) {      
-              size = oggplay_callback_info_get_record_size(headers[j]);
-              audio_data = oggplay_callback_info_get_audio_data(headers[j]);  
-              handle_audio_data(player, i, audio_data, channels * size);            
-          }          
-          //printf("audio presentation time: %llx\n",
-          //        oggplay_callback_info_get_presentation_time(headers[j]));                    
-#endif    
-          break;
-        case OGGPLAY_CMML:
-          if (oggplay_callback_info_get_required(track_info[i]) > 0)
-            printf("%s\n", oggplay_callback_info_get_text_data(headers[0]));
-          break;
-
-        case OGGPLAY_KATE:
-          required = oggplay_callback_info_get_required(track_info[i]);
-          for (j = 0; j < required; j++)
-            printf("[%d] %s\n", j, oggplay_callback_info_get_text_data(headers[j]));
-          break;
-
-        default:
-          break;
-      }
-    }    
-    n_frames++;
-    
-#if DISPLAY_FRAMES
-#if USE_AUDIO
-#ifdef WIN32	
-	//QueryPerformanceCounter(&last_tick_count);
-#endif
-#endif
-#if OPENGL
-    glutPostRedisplay();	
-#else
-    // send WM_PAINT to the player window
-	InvalidateRect(window, NULL, TRUE);
-	UpdateWindow(window);
-#endif
-#endif /* DISPLAY_FRAMES */
- 
-    oggplay_buffer_free_info(track_info);
-    oggplay_buffer_release_next (player);
-
-next_frame:
-    ReleaseSemaphore(sem, 1, NULL);
-#if !OPENGL
-  }
-#endif  
-}
-
-#if DISPLAY_FRAMES
-void show_window(void) {
-
-#if OPENGL
-  if (texture_bits != NULL) 
-  {
-
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width, 
-                    texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 
-                    texture_bits);
-
-  }
-  
-  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-  glBegin(GL_QUADS);
-  glTexCoord2f(0.0, texture_hscale);
-  glVertex2f(-1,-1);
-  glTexCoord2f(texture_wscale, texture_hscale);
-  glVertex2f(1,-1);  
-  glTexCoord2f(texture_wscale, 0.0);
-  glVertex2f(1,1);
-  glTexCoord2f(0.0, 0.0);
-  glVertex2f(-1,1);
-  glEnd();
-  glutSwapBuffers();
-#endif
-}
-#endif
-
-
-DWORD WINAPI drive_decoding(void *arg) {
-
-  while (1) { 
-    OggPlayErrorCode r;
-    WaitForSingleObject(sem, INFINITE);   
-
-	r = oggplay_step_decoding(player);
-
-    if (r != E_OGGPLAY_CONTINUE && r != E_OGGPLAY_USER_INTERRUPT) {
-#if DISPLAY_FRAMES
-#if OPENGL
-	  glutDestroyWindow(window);
-#endif
-#endif
-      // stop all treads and close the window 
-      SendMessage(window, WM_CLOSE, (WPARAM)0, (LPARAM)0);
-      Sleep(10);
-    }
-  }
-}
-
-
-#if !OPENGL
-void CreateDDBitmap(HDC hdc, HBITMAP* hBitmap) {
-
-	BITMAPINFOHEADER bih;
-	BITMAPINFO bmi;
-
-	// fill in BITMAPINFOHEADER
-	ZeroMemory(&bih, sizeof(BITMAPINFOHEADER));
-	bih.biClrImportant = 0;
-	bih.biClrUsed = 0;
-	bih.biXPelsPerMeter = 0;
-	bih.biYPelsPerMeter = 0;
-	bih.biSize = 40;
-	bih.biWidth = texture_width;
-	bih.biHeight = -texture_height;
-	bih.biPlanes = 1;
-	bih.biBitCount = 32;
-	bih.biCompression = BI_RGB;				
-	bih.biSizeImage = ((bih.biWidth * 32 + 31) & ~31) /8 * (-bih.biHeight);
-        //(((bih.biWidth * bih.biBitCount / 8) + 3) & ~3) * bih.biHeight;
-	
-	// fill in BITMAPINFO
-	ZeroMemory(&bmi, sizeof(BITMAPINFO));
-	bmi.bmiHeader = bih;	
-		
-	// create bitmap from raw rgb bits
-	SetDIBits(hdc, (*hBitmap), 0, texture_height, texture_bits, 
-						&bmi, DIB_RGB_COLORS);
-	/*SetDIBitsToDevice(hdc, 0, 0, texture_width, texture_height, 
-						0, 0, 0, texture_height, texture_bits, &bmi, DIB_RGB_COLORS);*/
-	return;
-}
-
-LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
-	PAINTSTRUCT ps;	
-	RECT r;
-	HDC hdc, hdcMem;
-	HBITMAP hbmOld, hbm;
-
-	BITMAP bm;
-	Player_Info* info = NULL;	
-
-    switch(message)
-    {
-		case WM_PAINT : {							
-		    hdc = BeginPaint(window, &ps);
-        GetClientRect(window, &r);
-				/* FIXME: very performance costly operations, use global context? */
-				hdcMem = CreateCompatibleDC(hdc);
-				hbm = CreateCompatibleBitmap(hdc, texture_width, texture_height);
-				CreateDDBitmap(hdc, &hbm);
-				hbmOld = SelectObject(hdcMem, hbm);
-				
-				if ((r.right - r.left != window_width) ||
-					(r.bottom - r.top != window_height)) {
-					StretchBlt(hdc, r.left, r.top, r.right - r.left, r.bottom - r.top, 
-						hdcMem, r.left, r.top, r.left + window_width, r.top + window_height,
-						SRCCOPY);
-				} else  {				
-					BitBlt(hdc, 0, 0, window_width, window_height, hdcMem, 
-						    0, 0, SRCCOPY);
-				}
-				//restore the initial state
-				SelectObject(hdcMem, hbmOld);
-				DeleteObject(hbm);
-                DeleteDC(hdcMem);                
-				EndPaint(window, &ps);
-			}
-			break;
-		case WM_CLOSE: {
-				info = (Player_Info*)GetWindowLong(window, GWL_USERDATA);
-				TerminateThread(info->decode_thread, (DWORD)0);
-        TerminateThread(info->display_thread, (DWORD)0);
-        CloseHandle(info->decode_thread);
-				CloseHandle(info->display_thread);
-        ExitProcess(0);
-        /*SuspendThread(info->decode_thread);
-				SuspendThread(info->display_thread);*/
-			}
-            break;
-        
-		case WM_DESTROY: {				
-				PostQuitMessage(0);
-			}
-            break;		
-		default:
-            return DefWindowProc(hWnd, message, wParam, lParam);
-
-	}
-	return 0;
-}
-
-int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int 
-				   nCmdShow) {
-#else
-int
-main (int argc, char * argv[]) {
-#endif
-	
-  OggPlayReader * reader;
-  int             i;  
-
-  MSG			  msg = {0};
-  WNDCLASSEX	  wc;
-  Player_Info	  info;
-  DWORD			  dec_id;
-  DWORD			  disp_id;  
-  LONG        offset = 0L;
-  BOOL fGotMessage;
-
-#if OPENGL
-  if (argc < 2) {
-    printf ("please provide a filename\n");
-    exit (1);
-  }
- 
-  if (strncmp(argv[1], "http://", 7) == 0) {
-    reader = oggplay_tcp_reader_new();
-  } else {
-    reader = oggplay_file_reader_new();
-  }
-
-  player = oggplay_open_with_reader(reader, argv[1]);
-#else
-  reader = oggplay_file_reader_new();
-  //reader = oggplay_tcp_reader_new();
-  //player = oggplay_open_with_reader(reader, "http://media.annodex.net/cmmlwiki/SFD2005-Trailer.axv");
-  player = oggplay_open_with_reader(reader, "E:\\_marcin\\_devel\\ogg_play\\index.anx");
-#endif
-
-  if (player == NULL) {
-    printf ("could not initialise oggplay with this file\n");
-    return 1;
-  }
-
-  printf ("there are %d tracks\n", oggplay_get_num_tracks (player));
-  
-  for (i = 0; i < oggplay_get_num_tracks (player); i++) {
-    printf("Track %d is of type %s\n", i, 
-                    oggplay_get_track_typename (player, i));
-    if (oggplay_get_track_type (player, i) == OGGZ_CONTENT_THEORA) {
-      oggplay_set_callback_num_frames (player, i, 1);
-      video_track = i;
-    }
-    else if (oggplay_get_track_type (player, i) == OGGZ_CONTENT_VORBIS) {
-      audio_track = i;
-      channels = 2;//oggplay_get_audio_channels(player, audio_track);
-  	  if (!channels)
-	  	  printf("Problems reading channel information\n");				
-	    rate = 16000;//oggplay_get_audio_samplerate(player, audio_track);
-  	  if (!rate)
-	  	  printf("Problems retreiving sample rate information\n");    
-      // calculate audio offset in [ms]
-      offset = (LONG)(1000 * BLOCK_SIZE * BLOCK_COUNT / channels / sizeof(short) / rate);      
-      printf("Calculated offset: %d\n", offset);
-      oggplay_set_offset(player, i, offset); 
-    }
-
-    if (oggplay_set_track_active(player, i) < 0) {
-      printf("\tNote: Could not set this track active!\n");
-    }
-  }
-
-#if DISPLAY_FRAMES
-#if OPENGL
-  glutInit(&argc, argv);
-  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
-  glutInitWindowPosition(100, 100);
-  glutInitWindowSize(400, 400);
-#endif /* !OPENGL */
-#endif /* !DISPLAY_FRAMES */
-  window_width = 400;
-  window_height = 400;
-#if DISPLAY_FRAMES
-#if OPENGL
-  window = glutCreateWindow("glut player");
-#else
-  // InitApplication
-  ZeroMemory(&wc, sizeof(WNDCLASSEX));
-  wc.cbSize = sizeof(WNDCLASSEX);
-  wc.style = 0; // thick frame?
-  wc.lpfnWndProc = WndProc;
-  wc.cbClsExtra = 0;
-  wc.cbWndExtra = 0;
-  wc.hInstance = hInstance;
-  wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
-  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
-  wc.lpszMenuName = NULL;
-  wc.lpszClassName = CLASSNAME;	
-  
-  if (!RegisterClassEx(&wc)) {
-  // end of InitApplication
- 	  printf("Window registration failed\n");
-	  return 1;
-  }
-  window_style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
-  // InitInstance
-  window = CreateWindowEx(WS_EX_CLIENTEDGE, CLASSNAME, APPLICATIONNAME, window_style, 
-						CW_USEDEFAULT, CW_USEDEFAULT, window_width, window_height,
-						NULL, NULL, hInstance, NULL);
-  // InitInstance
-  if (window == NULL) {
-	  printf("Window creation failed\n");		  
-	  return 1;  
-  }
-  // display and update window
-
-#endif
-#endif // DISPLAY_FRAMES
-
-  oggplay_use_buffer(player, OGGPLAY_BUFFER_SIZE);
-
-  audio_synch = CreateEvent(0, FALSE, FALSE, 0);
-  sem = CreateSemaphore(NULL, (long)OGGPLAY_BUFFER_SIZE, (long)OGGPLAY_BUFFER_SIZE, NULL);
-  
-  InitializeCriticalSection(&waveCriticalSection);
-  info.decode_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)drive_decoding, NULL, 0, &dec_id);  
-#if !OPENGL
-  info.display_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)display_frame, NULL, 0, &disp_id);    
-  SetWindowLong(window, GWL_USERDATA, (long)&info); 
-#endif
-
-#if DISPLAY_FRAMES
-#if OPENGL
-  glutIdleFunc(&display_frame);  
-  glutDisplayFunc(&show_window);
-  //glutDisplayFunc(&empty);
-
-  glEnable(GL_TEXTURE_2D);
-  glDisable(GL_CULL_FACE);
-  glBindTexture(GL_TEXTURE_2D, texture);
-  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
-  glGenTextures(1, &texture);
-
-  //nice(5);
-  
-  glutMainLoop();
-#else
-
-  // process window messages  
-  while ((fGotMessage = GetMessage(&msg, (HWND) NULL, 0, 0)) != 0 && fGotMessage != -1) 
-  { 
-	  TranslateMessage(&msg); 
-	  DispatchMessage(&msg); 
-  }
-  DeleteCriticalSection(&waveCriticalSection);  
-#endif  
-
-
-#else
-  while (1) {
-    display_frame(NULL);
-  }
-#endif /* !DISPLAY_FRAMES */
- 
-  printf("there were %d frames\n", n_frames);
-
-#if !OPENGL
-	return msg.wParam; 
-	UNREFERENCED_PARAMETER(lpCmdLine); 
-#endif
-}
+#include "config_win32.h"
+
+#include <oggplay/oggplay.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <windows.h>
+
+#include <Winbase.h>
+#define OPENGL 1
+
+#if OPENGL
+#include <glut.h> // requires OpenGL for Win32
+#endif /* !OPENGL */
+
+#define USE_AUDIO 0
+
+#if USE_AUDIO
+#include <mmreg.h>
+#include <math.h>
+#endif
+
+#include <assert.h>
+
+static int          n_frames = 0;
+static DWORD		position = 0;
+static UINT			target = 0;
+static DWORD		rate = 0;
+static UINT			channels = 2;
+static BOOL			buffering = TRUE;
+static BOOL			audio_opened = FALSE;
+
+static UINT         total_bytes = 0;
+
+#if OPENGL
+static GLuint texture;
+#endif
+
+#define OGGPLAY_BUFFER_SIZE 20
+#define BLOCK_SIZE  2560
+#define BLOCK_COUNT 4
+
+static unsigned char  *texture_bits = NULL;
+static int            texture_width;
+static int            texture_height;
+static float          texture_wscale;
+static float          texture_hscale;
+static int            window_width;
+static int            window_height;
+static int            window_style;
+
+static OggPlay*       player = NULL;
+
+static CRITICAL_SECTION waveCriticalSection;
+static HWAVEOUT			    hWaveOut;
+static WAVEHDR*         waveBlocks = NULL;
+static volatile int     waveFreeBlockCount;
+static int              waveCurrentBlock;
+
+static HANDLE			      audio_synch;
+typedef struct {
+  HANDLE           decode_thread;
+  HANDLE           display_thread;
+} Player_Info;
+
+
+// oggplay buffer underrun semaphore
+static HANDLE           sem;
+static HWAVEOUT         audio_dev;
+
+static int video_track;
+static int audio_track;
+
+
+#define APPLICATIONNAME TEXT("OggPlay Media Player\0")
+#define CLASSNAME       TEXT("OggPlayMediaPlayer\0")
+
+#if OPENGL
+static int        window;
+#else
+static HWND        window;
+#endif /*OPENGL*/
+
+#define DISPLAY_FRAMES 1
+
+void
+handle_video_data (OggPlay * player, int track_num, 
+                    OggPlayVideoData * video_data, int frame) {
+
+  int               i;      
+  int               y_width;
+  int               y_height;
+  int               uv_width;
+  int               uv_height;
+  int               po2_width;
+  int               po2_height;  
+  int				style;
+  OggPlayYUVChannels      yuv;
+  OggPlayRGBChannels      rgb;  
+  RECT				r;
+
+#if 0  
+  unsigned char*     ptry;
+  unsigned char*     ptru;
+  unsigned char*     ptrv;
+  unsigned char*     ptro;
+  unsigned char*     ptro2;
+#endif
+
+  oggplay_get_video_y_size(player, track_num, &y_width, &y_height);
+  if (y_width != window_width)
+  {
+#if DISPLAY_FRAMES
+#if OPENGL
+	glutReshapeWindow(y_width, y_height);
+#else    
+    style = window_style & ~ WS_OVERLAPPED;
+    GetClientRect(window, &r);
+	r.right = r.left + y_width + 5;
+	r.bottom = r.top + y_height + 5;
+	// allow for the border, title size, etc.
+	AdjustWindowRect(&r, style, FALSE);
+	SetWindowPos(window, HWND_TOP, 0, 0, 
+        r.right - r.left, r.bottom - r.top,
+		SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOMOVE | 
+		SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOZORDER | SWP_SHOWWINDOW);
+	UpdateWindow(window);
+#endif /* !OPENGL */
+#endif;
+    window_width = y_width;
+    window_height = y_height;
+  }
+    
+  oggplay_get_video_uv_size(player, track_num, &uv_width, &uv_height);
+  assert(uv_width == y_width / 2);
+  assert(uv_height == y_height / 2);
+  
+  for (po2_width = 1; po2_width < y_width; po2_width <<= 1);
+  for (po2_height = 1; po2_height < y_height; po2_height <<= 1);
+  texture_wscale = (float) y_width / po2_width;
+  texture_hscale = (float) y_height / po2_height;
+
+  if (texture_bits == NULL) {
+
+    texture_bits = (unsigned char*)calloc(1, po2_width * po2_height * 4);
+    texture_width = po2_width;
+    texture_height = po2_height;    
+    
+  } else if (texture_width != po2_width || texture_height != po2_height) {
+
+    free(texture_bits);
+    
+    texture_bits = (unsigned char*)calloc(1, po2_width * po2_height * 4);
+    texture_width = po2_width;
+    texture_height = po2_height;
+  }
+
+  /*
+   *  R = Y + 1.140V
+   *  G = Y - 0.395U - 0.581V
+   *  B = Y + 2.032U
+   */
+  
+  yuv.ptry = video_data->y;
+  yuv.ptru = video_data->u;
+  yuv.ptrv = video_data->v;
+  yuv.uv_width = uv_width;
+  yuv.uv_height = uv_height;  
+  yuv.y_width = y_width;
+  yuv.y_height = y_height;  
+  
+  rgb.ptro = texture_bits;
+  rgb.rgb_width = texture_width;
+  rgb.rgb_height = texture_height;  
+
+#if OPENGL
+  oggplay_yuv2rgba(&yuv, &rgb);
+#else
+  oggplay_yuv2bgra(&yuv, &rgb);
+#endif 
+
+}
+
+#if USE_AUDIO
+
+void
+float_to_short_array(const float* in, short* out, int len) {
+        int i = 0;
+        float scaled_value = 0;		
+        for(i = 0; i < len; i++) {				
+                scaled_value = floorf(0.5 + 32768 * in[i]);
+                if (in[i] < 0) {
+                   out[i] = (scaled_value < -32768.0) ? -32768 : (short)scaled_value;
+                } else {
+                   out[i] = (scaled_value > 32767.0) ? 32767 : (short)scaled_value;
+                }
+        }
+}
+
+WAVEHDR* allocateBlocks(int size, int count)
+{
+    unsigned char* buffer;    
+    int i;
+    WAVEHDR* blocks;
+    DWORD totalBufferSize = (size + sizeof(WAVEHDR)) * count;
+    
+    /*
+     * allocate memory for the entire set in one go     
+     */    
+    if((buffer = HeapAlloc(
+        GetProcessHeap(), 
+        HEAP_ZERO_MEMORY, 
+        totalBufferSize
+        )) == NULL) {
+        printf("Memory allocation error\n");
+        ExitProcess(1);
+    }
+
+    /*
+     * and set up the pointers to each bit
+     */
+    blocks = (WAVEHDR*)buffer;
+    buffer += sizeof(WAVEHDR) * count;
+    for(i = 0; i < count; i++) {
+        blocks[i].dwBufferLength = size;
+        blocks[i].lpData = buffer;
+        buffer += size;
+    }
+    
+    return blocks;
+}
+
+void freeBlocks(WAVEHDR* blockArray)
+{    
+	  /* 
+     * and this is why allocateBlocks works the way it does     
+     */     
+    HeapFree(GetProcessHeap(), 0, blockArray);
+}
+
+static void CALLBACK waveOutProc(
+    HWAVEOUT hWaveOut, 
+    UINT uMsg, 
+    DWORD dwInstance,  
+    DWORD dwParam1,    
+    DWORD dwParam2     
+)
+{
+    /*
+     * pointer to free block counter
+     */
+    int* freeBlockCounter = (int*)dwInstance;
+    /*
+     * ignore calls that occur due to openining and closing the
+     * device.
+     */
+    if(uMsg != WOM_DONE)
+        return;
+
+    EnterCriticalSection(&waveCriticalSection);
+    (*freeBlockCounter)++;
+    /*if ((*freeBlockCounter) == 1) 
+       SetEvent(audio_synch);*/
+    LeaveCriticalSection(&waveCriticalSection);	
+}
+
+void openAudio(OggPlay * player, int track) {
+	WAVEFORMATEX wfx;		
+	UINT fps = 25; // get from the stream information
+	UINT supported = FALSE;
+		
+	waveBlocks         = allocateBlocks(BLOCK_SIZE, BLOCK_COUNT);
+	waveFreeBlockCount = BLOCK_COUNT;
+  waveCurrentBlock   = 0;  
+ 	wfx.nSamplesPerSec  = (DWORD)rate;  /* sample rate */
+  wfx.wBitsPerSample  = 16;     /* sample size */
+  wfx.nChannels       = channels;      /* channels    */
+  wfx.cbSize          = 0;      /* size of _extra_ info */
+  wfx.wFormatTag      = WAVE_FORMAT_PCM;
+  wfx.nBlockAlign     = (wfx.wBitsPerSample * wfx.nChannels) >> 3;
+  wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
+	// target sample size in bytes for each frame
+	target				= wfx.nAvgBytesPerSec / fps; 	
+
+	supported = waveOutOpen(NULL, WAVE_MAPPER, &wfx, (DWORD_PTR)0, (DWORD_PTR)0, 
+		WAVE_FORMAT_QUERY);
+	if (supported == MMSYSERR_NOERROR) { // audio device sucessfully opened
+		waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER, &wfx, 
+	      (DWORD_PTR)waveOutProc, (DWORD_PTR)&waveFreeBlockCount, CALLBACK_FUNCTION);
+		//printf("Audio device sucessfully opened\n");
+	} else if (supported == WAVERR_BADFORMAT) {
+       printf("Requested format not supported...\n");
+       ExitProcess(1);
+	} else {
+       printf("Error opening default audio device. Exiting...\n");
+       ExitProcess(1);
+	}	
+  return;
+}
+
+
+void writeAudio(LPSTR data, int samples)
+{    
+	WAVEHDR* current;	
+  int bytes;
+	int remain;
+
+  current = &waveBlocks[waveCurrentBlock];
+  
+  while(samples > 0) {
+      /* 
+       * first make sure the header we're going to use is unprepared
+       */
+      if(current->dwFlags & WHDR_PREPARED) 
+          waveOutUnprepareHeader(hWaveOut, current, sizeof(WAVEHDR));
+	
+	    bytes = sizeof(short) * samples;
+      total_bytes += bytes;
+      if(bytes < (int)(BLOCK_SIZE - current->dwUser)) {						
+	  	    float_to_short_array((float*)data, (short*)(current->lpData + current->dwUser), samples);						
+		      //memcpy(current->lpData + current->dwUser, data, size);
+          current->dwUser += bytes;
+          break;
+      }
+	
+      // bytes is even as BLOCK_SIZE and dwUser are even too
+      bytes = BLOCK_SIZE - current->dwUser;
+	    remain = bytes / sizeof(short); // samples left in the buffer		
+      float_to_short_array((float*)data, (short*)(current->lpData + current->dwUser), remain);
+  		//memcpy(current->lpData + current->dwUser, data, remain);
+      samples -= remain;
+      data += 2 * bytes;		
+	    current->dwBufferLength = BLOCK_SIZE;
+	    waveOutPrepareHeader(hWaveOut, current, sizeof(WAVEHDR));
+	    waveOutWrite(hWaveOut, current, sizeof(WAVEHDR));
+      if (buffering == TRUE) {
+        printf("Total bytes %d\n", total_bytes);
+      }
+      buffering = FALSE;		
+      
+      EnterCriticalSection(&waveCriticalSection);
+      waveFreeBlockCount--;
+      LeaveCriticalSection(&waveCriticalSection);
+      /*
+       * wait for a block to become free
+       */
+      while (!waveFreeBlockCount) {        
+        //printf("All audio buffer blocks empty\n");        
+        //WaitForSingleObject(audio_synch, INFINITE);
+        Sleep(10);
+      }		  
+		
+      /*
+       * point to the next block
+       */
+      waveCurrentBlock++;
+      waveCurrentBlock %= BLOCK_COUNT;		
+
+      current = &waveBlocks[waveCurrentBlock];
+      current->dwUser = 0;
+  }
+}
+
+void 
+closeAudio() {
+  int i;
+  /*
+   * wait for all blocks to complete
+   */
+  while(waveFreeBlockCount < BLOCK_COUNT)
+	  Sleep(10);
+
+ /*
+  * unprepare any blocks that are still prepared
+  */
+  for(i = 0; i < waveFreeBlockCount; i++) 
+    if(waveBlocks[i].dwFlags & WHDR_PREPARED)
+	  waveOutUnprepareHeader(hWaveOut, &waveBlocks[i], sizeof(WAVEHDR));
+
+  freeBlocks(waveBlocks);
+  waveOutClose(hWaveOut);
+    
+}
+
+void
+handle_audio_data (OggPlay * player, int track, OggPlayAudioData * data, 
+                int size) {		
+	if (audio_opened == FALSE) {
+		openAudio(player, track);
+		audio_opened = TRUE;
+
+	}
+	writeAudio((LPSTR)data, size);  
+}
+#endif
+
+#if !OPENGL
+DWORD WINAPI display_frame(void *arg) {
+#else 
+void display_frame(void) {
+#endif
+  int                     i;
+  int                     j;
+  OggPlayDataHeader    ** headers;
+  OggPlayVideoData      * video_data;
+#if USE_AUDIO
+  OggPlayAudioData      * audio_data;
+#endif
+  int					  size;
+  int                     required;
+  OggPlayDataType         type;
+  int                     num_tracks;
+  OggPlayCallbackInfo  ** track_info;  
+  DWORD				            offset = 0;  
+  DWORD                   delay;
+  MMTIME                  mm;
+
+  delay = 40; // 40ms timeslots @ 25 fps
+
+  num_tracks = oggplay_get_num_tracks (player);
+
+  //nice(5);
+
+#if !OPENGL
+  while (1) { 
+#endif
+    track_info = oggplay_buffer_retrieve_next(player);
+    if (track_info == NULL) {
+#if DISPLAY_FRAMES
+      Sleep(delay);      
+
+#if OPENGL            
+      return;
+#else
+      continue;
+#endif
+    }
+#endif
+    // make sure the playback rate is correct
+	  if (buffering == FALSE) {		
+		  mm.wType = TIME_BYTES;		
+		  waveOutGetPosition(hWaveOut, &mm, sizeof(MMTIME));						  
+      if (target > (DWORD)mm.u.cb - position) {						  
+        offset = (target - (DWORD)mm.u.cb + position) * delay / target;												                               
+        Sleep(offset);
+		  }      
+		  position = (DWORD)mm.u.cb;
+	  }
+    for (i = 0; i < num_tracks; i++) {
+      type = oggplay_callback_info_get_type(track_info[i]);
+      headers = oggplay_callback_info_get_headers(track_info[i]);
+    
+      switch (type) {
+        case OGGPLAY_INACTIVE:
+          break;
+        case OGGPLAY_YUV_VIDEO:
+          /*
+           * there should only be one record
+           */
+          required = oggplay_callback_info_get_required(track_info[i]);
+          if (required == 0) {
+			oggplay_buffer_release(player, track_info);
+            goto next_frame;
+            }
+          video_data = oggplay_callback_info_get_video_data(headers[0]);
+          //printf("video presentation time: %llx\n",
+          //        oggplay_callback_info_get_presentation_time(headers[0]));
+          handle_video_data(player, i, video_data, n_frames);
+          break;
+        case OGGPLAY_FLOATS_AUDIO:
+#if USE_AUDIO
+          required = oggplay_callback_info_get_required(track_info[i]);          
+          // fill in fist and second buffer          
+          for (j = 0; j < required; j++) {      
+              size = oggplay_callback_info_get_record_size(headers[j]);
+              audio_data = oggplay_callback_info_get_audio_data(headers[j]);  
+              handle_audio_data(player, i, audio_data, channels * size);            
+          }          
+          //printf("audio presentation time: %llx\n",
+          //        oggplay_callback_info_get_presentation_time(headers[j]));                    
+#endif    
+          break;
+        case OGGPLAY_CMML:
+          if (oggplay_callback_info_get_required(track_info[i]) > 0)
+            printf("%s\n", oggplay_callback_info_get_text_data(headers[0]));
+          break;
+
+        case OGGPLAY_KATE:
+          required = oggplay_callback_info_get_required(track_info[i]);
+          for (j = 0; j < required; j++)
+            printf("[%d] %s\n", j, oggplay_callback_info_get_text_data(headers[j]));
+          break;
+
+        default:
+          break;
+      }
+    }    
+    n_frames++;
+    
+#if DISPLAY_FRAMES
+#if USE_AUDIO
+#ifdef WIN32	
+	//QueryPerformanceCounter(&last_tick_count);
+#endif
+#endif
+#if OPENGL
+    glutPostRedisplay();	
+#else
+    // send WM_PAINT to the player window
+	InvalidateRect(window, NULL, TRUE);
+	UpdateWindow(window);
+#endif
+#endif /* DISPLAY_FRAMES */
+
+	oggplay_buffer_release(player, track_info);
+
+next_frame:
+    ReleaseSemaphore(sem, 1, NULL);
+#if !OPENGL
+  }
+#endif  
+}
+
+#if DISPLAY_FRAMES
+void show_window(void) {
+
+#if OPENGL
+  if (texture_bits != NULL) 
+  {
+
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width, 
+                    texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 
+                    texture_bits);
+
+  }
+  
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  glBegin(GL_QUADS);
+  glTexCoord2f(0.0, texture_hscale);
+  glVertex2f(-1,-1);
+  glTexCoord2f(texture_wscale, texture_hscale);
+  glVertex2f(1,-1);  
+  glTexCoord2f(texture_wscale, 0.0);
+  glVertex2f(1,1);
+  glTexCoord2f(0.0, 0.0);
+  glVertex2f(-1,1);
+  glEnd();
+  glutSwapBuffers();
+#endif
+}
+#endif
+
+
+DWORD WINAPI drive_decoding(void *arg) {
+
+  while (1) { 
+    OggPlayErrorCode r;
+    WaitForSingleObject(sem, INFINITE);   
+
+	r = oggplay_step_decoding(player);
+
+    if (r != E_OGGPLAY_CONTINUE && r != E_OGGPLAY_USER_INTERRUPT) {
+#if DISPLAY_FRAMES
+#if OPENGL
+	  glutDestroyWindow(window);
+#endif
+#endif
+      // stop all treads and close the window 
+      SendMessage(window, WM_CLOSE, (WPARAM)0, (LPARAM)0);
+      Sleep(10);
+    }
+  }
+}
+
+
+#if !OPENGL
+void CreateDDBitmap(HDC hdc, HBITMAP* hBitmap) {
+
+	BITMAPINFOHEADER bih;
+	BITMAPINFO bmi;
+
+	// fill in BITMAPINFOHEADER
+	ZeroMemory(&bih, sizeof(BITMAPINFOHEADER));
+	bih.biClrImportant = 0;
+	bih.biClrUsed = 0;
+	bih.biXPelsPerMeter = 0;
+	bih.biYPelsPerMeter = 0;
+	bih.biSize = 40;
+	bih.biWidth = texture_width;
+	bih.biHeight = -texture_height;
+	bih.biPlanes = 1;
+	bih.biBitCount = 32;
+	bih.biCompression = BI_RGB;				
+	bih.biSizeImage = ((bih.biWidth * 32 + 31) & ~31) /8 * (-bih.biHeight);
+        //(((bih.biWidth * bih.biBitCount / 8) + 3) & ~3) * bih.biHeight;
+	
+	// fill in BITMAPINFO
+	ZeroMemory(&bmi, sizeof(BITMAPINFO));
+	bmi.bmiHeader = bih;	
+		
+	// create bitmap from raw rgb bits
+	SetDIBits(hdc, (*hBitmap), 0, texture_height, texture_bits, 
+						&bmi, DIB_RGB_COLORS);
+	/*SetDIBitsToDevice(hdc, 0, 0, texture_width, texture_height, 
+						0, 0, 0, texture_height, texture_bits, &bmi, DIB_RGB_COLORS);*/
+	return;
+}
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+	PAINTSTRUCT ps;	
+	RECT r;
+	HDC hdc, hdcMem;
+	HBITMAP hbmOld, hbm;
+
+	BITMAP bm;
+	Player_Info* info = NULL;	
+
+    switch(message)
+    {
+		case WM_PAINT : {							
+		    hdc = BeginPaint(window, &ps);
+        GetClientRect(window, &r);
+				/* FIXME: very performance costly operations, use global context? */
+				hdcMem = CreateCompatibleDC(hdc);
+				hbm = CreateCompatibleBitmap(hdc, texture_width, texture_height);
+				CreateDDBitmap(hdc, &hbm);
+				hbmOld = SelectObject(hdcMem, hbm);
+				
+				if ((r.right - r.left != window_width) ||
+					(r.bottom - r.top != window_height)) {
+					StretchBlt(hdc, r.left, r.top, r.right - r.left, r.bottom - r.top, 
+						hdcMem, r.left, r.top, r.left + window_width, r.top + window_height,
+						SRCCOPY);
+				} else  {				
+					BitBlt(hdc, 0, 0, window_width, window_height, hdcMem, 
+						    0, 0, SRCCOPY);
+				}
+				//restore the initial state
+				SelectObject(hdcMem, hbmOld);
+				DeleteObject(hbm);
+                DeleteDC(hdcMem);                
+				EndPaint(window, &ps);
+			}
+			break;
+		case WM_CLOSE: {
+				info = (Player_Info*)GetWindowLong(window, GWL_USERDATA);
+				TerminateThread(info->decode_thread, (DWORD)0);
+        TerminateThread(info->display_thread, (DWORD)0);
+        CloseHandle(info->decode_thread);
+				CloseHandle(info->display_thread);
+        ExitProcess(0);
+        /*SuspendThread(info->decode_thread);
+				SuspendThread(info->display_thread);*/
+			}
+            break;
+        
+		case WM_DESTROY: {				
+				PostQuitMessage(0);
+			}
+            break;		
+		default:
+            return DefWindowProc(hWnd, message, wParam, lParam);
+
+	}
+	return 0;
+}
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int 
+				   nCmdShow) {
+#else
+int
+main (int argc, char * argv[]) {
+#endif
+	
+  OggPlayReader * reader;
+  int             i;  
+
+  MSG			  msg = {0};
+  WNDCLASSEX	  wc;
+  Player_Info	  info;
+  DWORD			  dec_id;
+  DWORD			  disp_id;  
+  LONG        offset = 0L;
+  BOOL fGotMessage;
+
+#if OPENGL
+  if (argc < 2) {
+    printf ("please provide a filename\n");
+    exit (1);
+  }
+ 
+  if (strncmp(argv[1], "http://", 7) == 0) {
+    reader = oggplay_tcp_reader_new(argv[1], NULL, 0);
+  } else {
+    reader = oggplay_file_reader_new(argv[1]);
+  }
+
+  player = oggplay_open_with_reader(reader);
+#else
+  reader = oggplay_file_reader_new(lpCmdLine);
+  //reader = oggplay_tcp_reader_new();
+  //player = oggplay_open_with_reader(reader, "http://media.annodex.net/cmmlwiki/SFD2005-Trailer.axv");
+  //player = oggplay_open_with_reader(reader, "E:\\_marcin\\_devel\\ogg_play\\index.anx");
+  player = oggplay_open_with_reader(reader);
+#endif
+
+  if (player == NULL) {
+    printf ("could not initialise oggplay with this file\n");
+    return 1;
+  }
+
+  printf ("there are %d tracks\n", oggplay_get_num_tracks (player));
+  
+  for (i = 0; i < oggplay_get_num_tracks (player); i++) {
+    printf("Track %d is of type %s\n", i, 
+                    oggplay_get_track_typename (player, i));
+    if (oggplay_get_track_type (player, i) == OGGZ_CONTENT_THEORA) {
+      oggplay_set_callback_num_frames (player, i, 1);
+      video_track = i;
+    }
+    else if (oggplay_get_track_type (player, i) == OGGZ_CONTENT_VORBIS) {
+      audio_track = i;
+      channels = 2;//oggplay_get_audio_channels(player, audio_track);
+  	  if (!channels)
+	  	  printf("Problems reading channel information\n");				
+	    rate = 16000;//oggplay_get_audio_samplerate(player, audio_track);
+  	  if (!rate)
+	  	  printf("Problems retreiving sample rate information\n");    
+      // calculate audio offset in [ms]
+      offset = (LONG)(1000 * BLOCK_SIZE * BLOCK_COUNT / channels / sizeof(short) / rate);      
+      printf("Calculated offset: %d\n", offset);
+      oggplay_set_offset(player, i, offset); 
+    }
+
+    if (oggplay_set_track_active(player, i) < 0) {
+      printf("\tNote: Could not set this track active!\n");
+    }
+  }
+
+#if DISPLAY_FRAMES
+#if OPENGL
+  glutInit(&argc, argv);
+  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
+  glutInitWindowPosition(100, 100);
+  glutInitWindowSize(400, 400);
+#endif /* !OPENGL */
+#endif /* !DISPLAY_FRAMES */
+  window_width = 400;
+  window_height = 400;
+#if DISPLAY_FRAMES
+#if OPENGL
+  window = glutCreateWindow("glut player");
+#else
+  // InitApplication
+  ZeroMemory(&wc, sizeof(WNDCLASSEX));
+  wc.cbSize = sizeof(WNDCLASSEX);
+  wc.style = 0; // thick frame?
+  wc.lpfnWndProc = WndProc;
+  wc.cbClsExtra = 0;
+  wc.cbWndExtra = 0;
+  wc.hInstance = hInstance;
+  wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+  wc.lpszMenuName = NULL;
+  wc.lpszClassName = CLASSNAME;	
+  
+  if (!RegisterClassEx(&wc)) {
+  // end of InitApplication
+ 	  printf("Window registration failed\n");
+	  return 1;
+  }
+  window_style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
+  // InitInstance
+  window = CreateWindowEx(WS_EX_CLIENTEDGE, CLASSNAME, APPLICATIONNAME, window_style, 
+						CW_USEDEFAULT, CW_USEDEFAULT, window_width, window_height,
+						NULL, NULL, hInstance, NULL);
+  // InitInstance
+  if (window == NULL) {
+	  printf("Window creation failed\n");		  
+	  return 1;  
+  }
+  // display and update window
+
+#endif
+#endif // DISPLAY_FRAMES
+
+  oggplay_use_buffer(player, OGGPLAY_BUFFER_SIZE);
+
+  audio_synch = CreateEvent(0, FALSE, FALSE, 0);
+  sem = CreateSemaphore(NULL, (long)OGGPLAY_BUFFER_SIZE, (long)OGGPLAY_BUFFER_SIZE, NULL);
+  
+  InitializeCriticalSection(&waveCriticalSection);
+  info.decode_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)drive_decoding, NULL, 0, &dec_id);  
+#if !OPENGL
+  info.display_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)display_frame, NULL, 0, &disp_id);    
+  SetWindowLong(window, GWL_USERDATA, (long)&info); 
+#endif
+
+#if DISPLAY_FRAMES
+#if OPENGL
+  glutIdleFunc(&display_frame);  
+  glutDisplayFunc(&show_window);
+  //glutDisplayFunc(&empty);
+
+  glEnable(GL_TEXTURE_2D);
+  glDisable(GL_CULL_FACE);
+  glBindTexture(GL_TEXTURE_2D, texture);
+  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+  glGenTextures(1, &texture);
+
+  //nice(5);
+  
+  glutMainLoop();
+#else
+
+  // process window messages  
+  while ((fGotMessage = GetMessage(&msg, (HWND) NULL, 0, 0)) != 0 && fGotMessage != -1) 
+  { 
+	  TranslateMessage(&msg); 
+	  DispatchMessage(&msg); 
+  }
+  DeleteCriticalSection(&waveCriticalSection);  
+#endif  
+
+
+#else
+  while (1) {
+    display_frame(NULL);
+  }
+#endif /* !DISPLAY_FRAMES */
+ 
+  printf("there were %d frames\n", n_frames);
+
+#if !OPENGL
+	return msg.wParam; 
+//	UNREFERENCED_PARAMETER(lpCmdLine); 
+#endif
+}
\ No newline at end of file

Modified: liboggplay/trunk/win32/config_win32.h
===================================================================
--- liboggplay/trunk/win32/config_win32.h	2009-03-03 14:22:48 UTC (rev 3872)
+++ liboggplay/trunk/win32/config_win32.h	2009-03-04 01:40:33 UTC (rev 3873)
@@ -2,37 +2,37 @@
 /* config.h.in.  Generated from configure.ac by autoheader.  */
 
 /* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 0
+/* #undef HAVE_DLFCN_H */
 
 /* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 0
+/* #undef HAVE_INTTYPES_H */
 
 /* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 0
+/* #undef HAVE_MEMORY_H */
 
 /* Define if have liboggz */
-#define HAVE_OGGZ 
+#define HAVE_OGGZ 1
 
 /* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 0
+/* #undef HAVE_STDINT_H */
 
 /* Define to 1 if you have the <stdlib.h> header file. */
 #define HAVE_STDLIB_H 1
 
 /* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 0
+/* #undef HAVE_STRINGS_H */
 
 /* Define to 1 if you have the <string.h> header file. */
 #define HAVE_STRING_H 1
 
 /* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 0
+/* #undef HAVE_SYS_STAT_H */
 
 /* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 0
+/* #undef HAVE_SYS_TYPES_H */
 
 /* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 0
+/* #undef HAVE_UNISTD_H */
 
 /* Name of package */
 #define PACKAGE "liboggplay"
@@ -73,3 +73,6 @@
 
 /* Define to empty if `const' does not conform to ANSI C. */
 /* #undef const */
+
+/* Maximum supported data alignment */
+/* #undef ATTRIBUTE_ALIGNED_MAX */
\ No newline at end of file



More information about the commits mailing list