# HG changeset patch # User Ryan C. Gordon # Date 1288337986 14400 # Node ID 05a7b1d35ba97fec2179ccff636b9b67d9cbbd83 # Parent af33b35a55c12c2ed2c084e9964792e0acc481d0 Removed quicktime.c (use coreaudio.c instead). diff -r af33b35a55c1 -r 05a7b1d35ba9 decoders/Makefile.am --- a/decoders/Makefile.am Sat Oct 23 22:35:38 2010 -0700 +++ b/decoders/Makefile.am Fri Oct 29 03:39:46 2010 -0400 @@ -17,5 +17,5 @@ midi.c \ flac.c \ speex.c \ - quicktime.c \ + coreaudio.c \ wav.c diff -r af33b35a55c1 -r 05a7b1d35ba9 decoders/quicktime.c --- a/decoders/quicktime.c Sat Oct 23 22:35:38 2010 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,593 +0,0 @@ -/* - * SDL_sound -- An abstract sound format decoding API. - * Copyright (C) 2001 Ryan C. Gordon. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * QuickTime decoder for sound formats that QuickTime supports. - * April 28, 2002 - * - * This driver handles .mov files with a sound track. In - * theory, it could handle any format that QuickTime supports. - * In practice, it may only handle a select few of these formats. - * - * It seems able to play back AIFF and other standard Mac formats. - * Rewinding is not supported yet. - * - * The routine QT_create_data_ref() needs to be - * tweaked to support different media types. - * This code was originally written to get MP3 support, - * as it turns out, this isn't possible using this method. - * - * The only way to get streaming MP3 support through QuickTime, - * and hence support for SDL_RWops, is to write - * a DataHandler component, which suddenly gets much more difficult :-( - * - * This file was written by Darrell Walisser (walisser@mac.com) - * Portions have been borrowed from the "MP3Player" sample code, - * courtesy of Apple. - */ - -#if HAVE_CONFIG_H -# include -#endif - -#ifdef SOUND_SUPPORTS_QUICKTIME -#ifdef macintosh -typedef long int32_t; -# define OPAQUE_UPP_TYPES 0 -# include -#else -# include -# include -#endif - -#include -#include -#include -#include - -#include "SDL_sound.h" - -#define __SDL_SOUND_INTERNAL__ -#include "SDL_sound_internal.h" - -static int QT_init(void); -static void QT_quit(void); -static int QT_open(Sound_Sample *sample, const char *ext); -static void QT_close(Sound_Sample *sample); -static Uint32 QT_read(Sound_Sample *sample); -static int QT_rewind(Sound_Sample *sample); -static int QT_seek(Sound_Sample *sample, Uint32 ms); - -#define QT_MAX_INPUT_BUFFER (32*1024) /* Maximum size of internal buffer (internal->buffer_size) */ - -static const char *extensions_quicktime[] = { "MOV", NULL }; -const Sound_DecoderFunctions __Sound_DecoderFunctions_QuickTime = - { - { - extensions_quicktime, - "QuickTime format", - "Darrell Walisser ", - "http://www.icculus.org/SDL_sound/" - }, - - QT_init, /* init() method */ - QT_quit, /* quit() method */ - QT_open, /* open() method */ - QT_close, /* close() method */ - QT_read, /* read() method */ - QT_rewind, /* rewind() method */ - QT_seek /* seek() method */ - }; - -typedef struct { - - ExtendedSoundComponentData compData; - Handle hSource; /* source media buffer */ - Media sourceMedia; /* sound media identifier */ - TimeValue getMediaAtThisTime; - TimeValue sourceDuration; - Boolean isThereMoreSource; - UInt32 maxBufferSize; - -} SCFillBufferData, *SCFillBufferDataPtr; - -typedef struct { - - Movie movie; - Track track; - Media media; - AudioFormatAtomPtr atom; - SoundComponentData source_format; - SoundComponentData dest_format; - SoundConverter converter; - SCFillBufferData buffer_data; - SoundConverterFillBufferDataUPP fill_buffer_proc; - -} qt_t; - - - - -/* - * This procedure creates a description of the raw data - * read from SDL_RWops so that QuickTime can identify - * the codec it needs to use to decompress it. - */ -static Handle QT_create_data_ref (const char *file_extension) { - - Handle tmp_handle, data_ref; - StringPtr file_name = "\p"; /* empty since we don't know the file name! */ - OSType file_type; - StringPtr mime_type; - long atoms[3]; - -/* - if (__Sound_strcasecmp (file_extension, "mp3")==0) { - file_type = 'MPEG'; - mime_type = "\pvideo/mpeg"; - } - else { - - return NULL; - } -*/ - - if (__Sound_strcasecmp (file_extension, "mov") == 0) { - - file_type = 'MooV'; - mime_type = "\pvideo/quicktime"; - } - else { - - return NULL; - } - - tmp_handle = NewHandle(0); - assert (tmp_handle != NULL); - assert (noErr == PtrToHand (&tmp_handle, &data_ref, sizeof(Handle))); - assert (noErr == PtrAndHand (file_name, data_ref, file_name[0]+1)); - - atoms[0] = EndianU32_NtoB (sizeof(long) * 3); - atoms[1] = EndianU32_NtoB (kDataRefExtensionMacOSFileType); - atoms[2] = EndianU32_NtoB (file_type); - - assert (noErr == PtrAndHand (atoms, data_ref, sizeof(long)*3)); - - atoms[0] = EndianU32_NtoB (sizeof(long)*2 + mime_type[0]+1); - atoms[1] = EndianU32_NtoB (kDataRefExtensionMIMEType); - - assert (noErr == PtrAndHand (atoms, data_ref, sizeof(long)*2)); - assert (noErr == PtrAndHand (mime_type, data_ref, mime_type[0]+1)); - - return data_ref; -} - -/* - * This procedure is a hook for QuickTime to grab data from the - * SDL_RWOps data structure when it needs it - */ -static pascal OSErr QT_get_movie_data_proc (long offset, long size, - void *data, void *user_data) -{ - SDL_RWops* rw = (SDL_RWops*)user_data; - OSErr error; - - if (offset == SDL_RWseek (rw, offset, SEEK_SET)) { - - if (size == SDL_RWread (rw, data, 1, size)) { - error = noErr; - } - else { - error = notEnoughDataErr; - } - } - else { - error = fileOffsetTooBigErr; - } - - return (error); -} - -/* * ---------------------------- - * SoundConverterFillBufferDataProc - * - * the callback routine that provides the source data for conversion - - * it provides data by setting outData to a pointer to a properly - * filled out ExtendedSoundComponentData structure - */ -static pascal Boolean QT_sound_converter_fill_buffer_data_proc (SoundComponentDataPtr *outData, void *inRefCon) -{ - SCFillBufferDataPtr pFillData = (SCFillBufferDataPtr)inRefCon; - - OSErr err = noErr; - - /* if after getting the last chunk of data the total time is over - * the duration, we're done - */ - if (pFillData->getMediaAtThisTime >= pFillData->sourceDuration) { - pFillData->isThereMoreSource = false; - pFillData->compData.desc.buffer = NULL; - pFillData->compData.desc.sampleCount = 0; - pFillData->compData.bufferSize = 0; - } - - if (pFillData->isThereMoreSource) { - - long sourceBytesReturned; - long numberOfSamples; - TimeValue sourceReturnedTime, durationPerSample; - - HUnlock(pFillData->hSource); - - err = GetMediaSample - (pFillData->sourceMedia,/* specifies the media for this operation */ - pFillData->hSource, /* function returns the sample data into this handle */ - pFillData->maxBufferSize, /* maximum number of bytes of sample data to be returned */ - &sourceBytesReturned, /* the number of bytes of sample data returned */ - pFillData->getMediaAtThisTime,/* starting time of the sample to - be retrieved (must be in - Media's TimeScale) */ - &sourceReturnedTime,/* indicates the actual time of the returned sample data */ - &durationPerSample, /* duration of each sample in the media */ - NULL, /* sample description corresponding to the returned sample data (NULL to ignore) */ - NULL, /* index value to the sample description that corresponds - to the returned sample data (NULL to ignore) */ - 0, /* maximum number of samples to be returned (0 to use a - value that is appropriate for the media) */ - &numberOfSamples, /* number of samples it actually returned */ - NULL); /* flags that describe the sample (NULL to ignore) */ - - HLock(pFillData->hSource); - - if ((noErr != err) || (sourceBytesReturned == 0)) { - pFillData->isThereMoreSource = false; - pFillData->compData.desc.buffer = NULL; - pFillData->compData.desc.sampleCount = 0; - - if ((err != noErr) && (sourceBytesReturned > 0)) - DebugStr("\pGetMediaSample - Failed in FillBufferDataProc"); - } - - pFillData->getMediaAtThisTime = sourceReturnedTime + (durationPerSample * numberOfSamples); - pFillData->compData.bufferSize = sourceBytesReturned; - } - - /* set outData to a properly filled out ExtendedSoundComponentData struct */ - *outData = (SoundComponentDataPtr)&pFillData->compData; - - return (pFillData->isThereMoreSource); -} - - -static int QT_init_internal () { - - OSErr error; - - error = EnterMovies(); /* initialize the movie toolbox */ - - return (error == noErr); -} - -static void QT_quit_internal () { - - ExitMovies(); -} - -static qt_t* QT_open_internal (Sound_Sample *sample, const char *extension) -{ - Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; - - qt_t *instance; - OSErr error; - Movie movie; - Track sound_track; - Media sound_track_media; - AudioFormatAtomPtr source_sound_decomp_atom; - - SoundDescriptionV1Handle source_sound_description; - Handle source_sound_description_extension; - Size source_sound_description_extension_size; - Handle data_ref; - - data_ref = QT_create_data_ref (extension); - - /* create a movie that will read data using SDL_RWops */ - error = NewMovieFromUserProc - (&movie, - 0, - NULL, - NewGetMovieUPP(QT_get_movie_data_proc), - (void*) internal->rw, - data_ref, - 'hndl'); - - if (error != noErr) { - - return NULL; - } - - /* get the first sound track of the movie; other tracks will be ignored */ - sound_track = GetMovieIndTrackType (movie, 1, SoundMediaType, movieTrackMediaType); - if (sound_track == NULL) { - - /* movie needs a sound track! */ - - return NULL; - } - - /* get and return the sound track media */ - sound_track_media = GetTrackMedia (sound_track); - if (sound_track_media == NULL) { - - return NULL; - } - - /* create a description of the source sound so we can convert it later */ - source_sound_description = (SoundDescriptionV1Handle)NewHandle(0); - assert (source_sound_description != NULL); /* out of memory */ - - GetMediaSampleDescription (sound_track_media, 1, - (SampleDescriptionHandle)source_sound_description); - error = GetMoviesError(); - if (error != noErr) { - - return NULL; - } - - source_sound_description_extension = NewHandle(0); - assert (source_sound_description_extension != NULL); /* out of memory */ - - error = GetSoundDescriptionExtension ((SoundDescriptionHandle) source_sound_description, - &source_sound_description_extension, - siDecompressionParams); - - if (error == noErr) { - - /* copy extension to atom format description if we have an extension */ - - source_sound_description_extension_size = - GetHandleSize (source_sound_description_extension); - HLock (source_sound_description_extension); - - source_sound_decomp_atom = (AudioFormatAtom*) - NewPtr (source_sound_description_extension_size); - assert (source_sound_decomp_atom != NULL); /* out of memory */ - - BlockMoveData (*source_sound_description_extension, - source_sound_decomp_atom, - source_sound_description_extension_size); - - HUnlock (source_sound_description_extension); - } - - else { - - source_sound_decomp_atom = NULL; - } - - instance = (qt_t*) malloc (sizeof(*instance)); - assert (instance != NULL); /* out of memory */ - - instance->movie = movie; - instance->track = sound_track; - instance->media = sound_track_media; - instance->atom = source_sound_decomp_atom; - - instance->source_format.flags = 0; - instance->source_format.format = (*source_sound_description)->desc.dataFormat; - instance->source_format.numChannels = (*source_sound_description)->desc.numChannels; - instance->source_format.sampleSize = (*source_sound_description)->desc.sampleSize; - instance->source_format.sampleRate = (*source_sound_description)->desc.sampleRate; - instance->source_format.sampleCount = 0; - instance->source_format.buffer = NULL; - instance->source_format.reserved = 0; - - instance->dest_format.flags = 0; - instance->dest_format.format = kSoundNotCompressed; - instance->dest_format.numChannels = (*source_sound_description)->desc.numChannels; - instance->dest_format.sampleSize = (*source_sound_description)->desc.sampleSize; - instance->dest_format.sampleRate = (*source_sound_description)->desc.sampleRate; - instance->dest_format.sampleCount = 0; - instance->dest_format.buffer = NULL; - instance->dest_format.reserved = 0; - - sample->actual.channels = (*source_sound_description)->desc.numChannels; - sample->actual.rate = (*source_sound_description)->desc.sampleRate >> 16; - - if ((*source_sound_description)->desc.sampleSize == 16) { - - sample->actual.format = AUDIO_S16SYS; - } - else if ((*source_sound_description)->desc.sampleSize == 8) { - - sample->actual.format = AUDIO_U8; - } - else { - - /* 24-bit or others... (which SDL can't handle) */ - return NULL; - } - - DisposeHandle (source_sound_description_extension); - DisposeHandle ((Handle)source_sound_description); - - /* This next code sets up the SoundConverter component */ - error = SoundConverterOpen (&instance->source_format, &instance->dest_format, - &instance->converter); - - if (error != noErr) { - - return NULL; - } - - error = SoundConverterSetInfo (instance->converter, siDecompressionParams, - instance->atom); - if (error == siUnknownInfoType) { - - /* ignore */ - } - else if (error != noErr) { - - /* reall error */ - return NULL; - } - - error = SoundConverterBeginConversion (instance->converter); - if (error != noErr) { - - return NULL; - } - - instance->buffer_data.sourceMedia = instance->media; - instance->buffer_data.getMediaAtThisTime = 0; - instance->buffer_data.sourceDuration = GetMediaDuration(instance->media); - instance->buffer_data.isThereMoreSource = true; - instance->buffer_data.maxBufferSize = QT_MAX_INPUT_BUFFER; - /* allocate source media buffer */ - instance->buffer_data.hSource = NewHandle((long)instance->buffer_data.maxBufferSize); - assert (instance->buffer_data.hSource != NULL); /* out of memory */ - - instance->buffer_data.compData.desc = instance->source_format; - instance->buffer_data.compData.desc.buffer = (Byte *)*instance->buffer_data.hSource; - instance->buffer_data.compData.desc.flags = kExtendedSoundData; - instance->buffer_data.compData.recordSize = sizeof(ExtendedSoundComponentData); - instance->buffer_data.compData.extendedFlags = - kExtendedSoundSampleCountNotValid | kExtendedSoundBufferSizeValid; - instance->buffer_data.compData.bufferSize = 0; - - instance->fill_buffer_proc = - NewSoundConverterFillBufferDataUPP (QT_sound_converter_fill_buffer_data_proc); - - return (instance); - -} /* QT_open_internal */ - -static void QT_close_internal (qt_t *instance) -{ - -} /* QT_close_internal */ - -static Uint32 QT_read_internal(Sound_Sample *sample) -{ - Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; - qt_t *instance = (qt_t*) internal->decoder_private; - long output_bytes, output_frames, output_flags; - OSErr error; - - error = SoundConverterFillBuffer - (instance->converter, /* a sound converter */ - instance->fill_buffer_proc, /* the callback UPP */ - &instance->buffer_data, /* refCon passed to FillDataProc */ - internal->buffer, /* the decompressed data 'play' buffer */ - internal->buffer_size, /* size of the 'play' buffer */ - &output_bytes, /* number of output bytes */ - &output_frames, /* number of output frames */ - &output_flags); /* fillbuffer retured advisor flags */ - - if (output_flags & kSoundConverterHasLeftOverData) { - - sample->flags |= SOUND_SAMPLEFLAG_EAGAIN; - } - else { - - sample->flags |= SOUND_SAMPLEFLAG_EOF; - } - - if (error != noErr) { - - sample->flags |= SOUND_SAMPLEFLAG_ERROR; - } - - return (output_bytes); - -} /* QT_read_internal */ - -static int QT_rewind_internal (Sound_Sample *sample) -{ - - return 0; - -} /* QT_rewind_internal */ - - - -static int QT_init(void) -{ - return (QT_init_internal()); - -} /* QT_init */ - -static void QT_quit(void) -{ - QT_quit_internal(); - -} /* QT_quit */ - -static int QT_open(Sound_Sample *sample, const char *ext) -{ - Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; - qt_t *instance; - - instance = QT_open_internal(sample, ext); - internal->decoder_private = (void*)instance; - - internal->total_time = -1; /* return -1 for total time of song for now */ - - return(instance != NULL); - -} /* QT_open */ - - -static void QT_close(Sound_Sample *sample) -{ - Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; - qt_t *instance = (qt_t *) internal->decoder_private; - - QT_close_internal (instance); - - free (instance); - -} /* QT_close */ - - -static Uint32 QT_read(Sound_Sample *sample) -{ - return(QT_read_internal(sample)); - -} /* QT_read */ - - -static int QT_rewind(Sound_Sample *sample) -{ - - return(QT_rewind_internal(sample)); - -} /* QT_rewind */ - - -static int QT_seek(Sound_Sample *sample, Uint32 ms) -{ - BAIL_MACRO("QUICKTIME: Seeking not implemented", 0); -} /* QT_seek */ - - -#endif /* SOUND_SUPPORTS_QUICKTIME */ - -/* end of quicktime.c ... */ -