[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