We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 411

Summary: ov_open fails in Windows when compilling with visual C in dinamic form.
Product: SDL_mixer Reporter: Richard Natal <bigous>
Component: miscAssignee: Ryan C. Gordon <icculus>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: slouken
Version: unspecified   
Hardware: x86   
OS: Windows (All)   
URL: http://xiph.org/vorbis/doc/vorbisfile/ov_open.html

Description Richard Natal 2007-03-06 13:02:23 UTC
As you can see at this link: http://xiph.org/vorbis/doc/vorbisfile/ov_open.html
Call ov_open loading it with LoadLibrary using visual C compiler/libraries may fail because of multiples CRT in memory.
The bug is in file dynamic_ogg.c because it calls ov_open.
I've made a small correction in my PC and it works now... the entire file is listed here. See the 2 #ifdef WIN32 blocks to see what was made.
Sorry about my poor english ... An as I'm new to bugzilla and SDL, sorry if I didn't submit the code throw SVN (I've never made this... if someone could teach me...)
[]s
Richard (Bigous)

/*
    SDL_mixer:  An audio mixer library based on the SDL library
    Copyright (C) 1997-2004 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Sam Lantinga
    slouken@libsdl.org
*/

#ifdef OGG_MUSIC

#include "SDL/SDL_loadso.h"

#include "dynamic_ogg.h"

vorbis_loader vorbis = {
	0, NULL
};

#ifdef OGG_DYNAMIC

#ifdef WIN32
/*
 * In Win32, dinamic link vorbis and call ov_open causes access violation is some circunstances.
 * It's better explained here: http://xiph.org/vorbis/doc/vorbisfile/ov_open.html
 * This is a work arround to make the SDL_mixer work correctly in Windows.
 * []s Bigous
 */

static int bigous_fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
  if(f==NULL)return(-1);
  return fseek(f,(long)off,whence);
}

ov_callbacks bigous_callbacks = {
  (size_t (*)(void *, size_t, size_t, void *))  fread,
  (int (*)(void *, ogg_int64_t, int))           bigous_fseek64_wrap,
  (int (*)(void *))                             fclose,
  (long (*)(void *))                            ftell
};

int bigous_ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes)
{
	return vorbis.ov_open_callbacks(f, vf, initial, ibytes, bigous_callbacks);
}

#endif

int Mix_InitOgg()
{
	if ( vorbis.loaded == 0 ) {
		vorbis.handle = SDL_LoadObject(OGG_DYNAMIC);
		if ( vorbis.handle == NULL ) {
			return -1;
		}
		vorbis.ov_clear =
			(int (*)(OggVorbis_File *))
			SDL_LoadFunction(vorbis.handle, "ov_clear");
		if ( vorbis.ov_clear == NULL ) {
			SDL_UnloadObject(vorbis.handle);
			return -1;
		}
		vorbis.ov_info =
			(vorbis_info *(*)(OggVorbis_File *,int))
			SDL_LoadFunction(vorbis.handle, "ov_info");
		if ( vorbis.ov_info == NULL ) {
			SDL_UnloadObject(vorbis.handle);
			return -1;
		}
		vorbis.ov_open =
#ifdef WIN32
			bigous_ov_open;
#else
			(int (*)(FILE *,OggVorbis_File *,char *,long))
			SDL_LoadFunction(vorbis.handle, "ov_open");
#endif
		if ( vorbis.ov_open == NULL ) {
			SDL_UnloadObject(vorbis.handle);
			return -1;
		}
		vorbis.ov_open_callbacks =
			(int (*)(void *, OggVorbis_File *, char *, long, ov_callbacks))
			SDL_LoadFunction(vorbis.handle, "ov_open_callbacks");
		if ( vorbis.ov_open_callbacks == NULL ) {
			SDL_UnloadObject(vorbis.handle);
			return -1;
		}
		vorbis.ov_pcm_total =
			(ogg_int64_t (*)(OggVorbis_File *,int))
			SDL_LoadFunction(vorbis.handle, "ov_pcm_total");
		if ( vorbis.ov_pcm_total == NULL ) {
			SDL_UnloadObject(vorbis.handle);
			return -1;
		}
		vorbis.ov_read =
			(long (*)(OggVorbis_File *,char *,int, int,int,int,int *))
			SDL_LoadFunction(vorbis.handle, "ov_read");
		if ( vorbis.ov_read == NULL ) {
			SDL_UnloadObject(vorbis.handle);
			return -1;
		}
		vorbis.ov_time_seek =
			(int (*)(OggVorbis_File *,double))
			SDL_LoadFunction(vorbis.handle, "ov_time_seek");
		if ( vorbis.ov_time_seek == NULL ) {
			SDL_UnloadObject(vorbis.handle);
			return -1;
		}
	}
	++vorbis.loaded;

	return 0;
}
void Mix_QuitOgg()
{
	if ( vorbis.loaded == 0 ) {
		return;
	}
	if ( vorbis.loaded == 1 ) {
		SDL_UnloadObject(vorbis.handle);
	}
	--vorbis.loaded;
}
#else
int Mix_InitOgg()
{
	if ( vorbis.loaded == 0 ) {
		vorbis.ov_clear = ov_clear;
		vorbis.ov_info = ov_info;
		vorbis.ov_open = ov_open;
		vorbis.ov_open_callbacks = ov_open_callbacks;
		vorbis.ov_pcm_total = ov_pcm_total;
		vorbis.ov_read = ov_read;
		vorbis.ov_time_seek = ov_time_seek;
	}
	++vorbis.loaded;

	return 0;
}
void Mix_QuitOgg()
{
	if ( vorbis.loaded == 0 ) {
		return;
	}
	if ( vorbis.loaded == 1 ) {
	}
	--vorbis.loaded;
}
#endif /* OGG_DYNAMIC */

#endif /* OGG_MUSIC */
Comment 1 Sam Lantinga 2007-07-14 21:09:50 UTC
This is fixed in subversion revision 3275.  Thanks!