revamp OggFLAC__SeekableStreamDecoder to derive from OggFLAC__StreamDecoder instead of FLAC__SeekableStreamDecoder; rewrite seek routine to do a binary search through Ogg pages, instead of the seektable-based search of FLAC__SeekableStreamDecoder

This commit is contained in:
Josh Coalson 2004-07-07 07:35:02 +00:00
parent 6ebbabfd34
commit 63f8edc69c
10 changed files with 640 additions and 319 deletions

View File

@ -209,7 +209,7 @@ namespace OggFLAC {
bool set_metadata_ignore_all();
State get_state() const;
FLAC::Decoder::SeekableStream::State get_FLAC_seekable_stream_decoder_state() const;
OggFLAC::Decoder::Stream::State get_stream_decoder_state() const;
FLAC::Decoder::Stream::State get_FLAC_stream_decoder_state() const;
bool get_md5_checking() const;
unsigned get_channels() const;
@ -231,10 +231,10 @@ namespace OggFLAC {
bool seek_absolute(FLAC__uint64 sample);
protected:
virtual ::FLAC__SeekableStreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes) = 0;
virtual ::FLAC__SeekableStreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset) = 0;
virtual ::FLAC__SeekableStreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset) = 0;
virtual ::FLAC__SeekableStreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length) = 0;
virtual ::OggFLAC__SeekableStreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes) = 0;
virtual ::OggFLAC__SeekableStreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset) = 0;
virtual ::OggFLAC__SeekableStreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset) = 0;
virtual ::OggFLAC__SeekableStreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length) = 0;
virtual bool eof_callback() = 0;
virtual ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]) = 0;
virtual void metadata_callback(const ::FLAC__StreamMetadata *metadata) = 0;
@ -246,10 +246,10 @@ namespace OggFLAC {
#endif
::OggFLAC__SeekableStreamDecoder *decoder_;
private:
static ::FLAC__SeekableStreamDecoderReadStatus read_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
static ::FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
static ::FLAC__SeekableStreamDecoderTellStatus tell_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
static ::FLAC__SeekableStreamDecoderLengthStatus length_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
static ::OggFLAC__SeekableStreamDecoderReadStatus read_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
static ::OggFLAC__SeekableStreamDecoderSeekStatus seek_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
static ::OggFLAC__SeekableStreamDecoderTellStatus tell_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
static ::OggFLAC__SeekableStreamDecoderLengthStatus length_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
static FLAC__bool eof_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, void *client_data);
static ::FLAC__StreamDecoderWriteStatus write_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
static void metadata_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, const ::FLAC__StreamMetadata *metadata, void *client_data);
@ -311,7 +311,7 @@ namespace OggFLAC {
State get_state() const;
OggFLAC::Decoder::SeekableStream::State get_seekable_stream_decoder_state() const;
FLAC::Decoder::SeekableStream::State get_FLAC_seekable_stream_decoder_state() const;
OggFLAC::Decoder::Stream::State get_stream_decoder_state() const;
FLAC::Decoder::Stream::State get_FLAC_stream_decoder_state() const;
bool get_md5_checking() const;
unsigned get_channels() const;

View File

@ -118,7 +118,7 @@ extern OggFLAC_API const char * const OggFLAC__FileDecoderStateString[];
/***********************************************************************
*
* class OggFLAC__FileDecoder : public FLAC__FileDecoder
* class OggFLAC__FileDecoder : public OggFLAC__SeekableStreamDecoder
*
***********************************************************************/
@ -421,27 +421,27 @@ OggFLAC_API OggFLAC__FileDecoderState OggFLAC__file_decoder_get_state(const OggF
*/
OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__file_decoder_get_seekable_stream_decoder_state(const OggFLAC__FileDecoder *decoder);
/** Get the state of the underlying FLAC seekable stream decoder.
/** Get the state of the underlying stream decoder.
* Useful when the file decoder state is
* \c OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR
* and the seekable stream decoder state is
* \c OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR.
* \c OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR.
*
* \param decoder A decoder instance to query.
* \assert
* \code decoder != NULL \endcode
* \retval FLAC__SeekableStreamDecoderState
* The FLAC seekable stream decoder state.
* \retval OggFLAC__StreamDecoderState
* The stream decoder state.
*/
OggFLAC_API FLAC__SeekableStreamDecoderState OggFLAC__file_decoder_get_FLAC_seekable_stream_decoder_state(const OggFLAC__FileDecoder *decoder);
OggFLAC_API OggFLAC__StreamDecoderState OggFLAC__file_decoder_get_stream_decoder_state(const OggFLAC__FileDecoder *decoder);
/** Get the state of the underlying FLAC stream decoder.
* Useful when the file decoder state is
* \c OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR
* and the seekable stream decoder state is
* \c OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR
* and the * FLAC seekable stream decoder state is
* \c FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR.
* \c OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR
* and the stream decoder state is
* \c OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR.
*
* \param decoder A decoder instance to query.
* \assert
@ -530,6 +530,8 @@ OggFLAC_API unsigned OggFLAC__file_decoder_get_sample_rate(const OggFLAC__FileDe
*/
OggFLAC_API unsigned OggFLAC__file_decoder_get_blocksize(const OggFLAC__FileDecoder *decoder);
#if 0
@@@@@@ this can never be made to work without writing a custom Ogg decoder; remove for release
/** This is inherited from FLAC__FileDecoder; see
* FLAC__file_decoder_get_decode_position().
*
@ -543,6 +545,7 @@ OggFLAC_API unsigned OggFLAC__file_decoder_get_blocksize(const OggFLAC__FileDeco
* the 'tell' callback.
*/
OggFLAC_API FLAC__bool OggFLAC__file_decoder_get_decode_position(const OggFLAC__FileDecoder *decoder, FLAC__uint64 *position);
#endif
/** Initialize the decoder instance.
* Should be called after OggFLAC__file_decoder_new() and
@ -614,8 +617,8 @@ OggFLAC_API FLAC__bool OggFLAC__file_decoder_process_until_end_of_metadata(OggFL
*/
OggFLAC_API FLAC__bool OggFLAC__file_decoder_process_until_end_of_file(OggFLAC__FileDecoder *decoder);
/** This is inherited from FLAC__FileDecoder; see
* FLAC__file_decoder_seek_absolute().
/** This is inherited from OggFLAC__SeekableStreamDecoder; see
* OggFLAC__seekable_stream_decoder_seek_absolute().
*
* \param decoder A decoder instance.
* \param sample The target sample number to seek to.

View File

@ -33,8 +33,7 @@
#define OggFLAC__SEEKABLE_STREAM_DECODER_H
#include "export.h"
#include "FLAC/seekable_stream_decoder.h"
#include "stream_decoder.h"
#ifdef __cplusplus
extern "C" {
@ -77,22 +76,27 @@ typedef enum {
OggFLAC__SEEKABLE_STREAM_DECODER_OK = 0,
/**< The decoder is in the normal OK state. */
OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING,
/**< The decoder is in the process of seeking. */
OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM,
/**< The decoder has reached the end of the stream. */
OggFLAC__SEEKABLE_STREAM_DECODER_OGG_ERROR,
/**< An error occurred in the underlying Ogg layer. */
OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR,
/**< Memory allocation failed. */
OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR,
/**< An error occurred in the underlying FLAC seekable stream decoder;
* check OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state().
OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR,
/**< An error occurred in the underlying stream decoder;
* check OggFLAC__seekable_stream_decoder_get_stream_decoder_state().
*/
OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR,
/**< The read callback returned an error. */
OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR,
/**< Memory allocation failed. */
OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR,
/**< An error occurred while seeking or the seek or tell
* callback returned an error.
*/
OggFLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED,
/**< OggFLAC__seekable_stream_decoder_init() was called when the decoder was
@ -116,6 +120,86 @@ typedef enum {
extern OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderStateString[];
/** Return values for the OggFLAC__SeekableStreamDecoder read callback.
*/
typedef enum {
OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK,
/**< The read was OK and decoding can continue. */
OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR
/**< An unrecoverable error occurred. The decoder will return from the process call. */
} OggFLAC__SeekableStreamDecoderReadStatus;
/** Maps a OggFLAC__SeekableStreamDecoderReadStatus to a C string.
*
* Using a OggFLAC__SeekableStreamDecoderReadStatus as the index to this array
* will give the string equivalent. The contents should not be modified.
*/
extern OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderReadStatusString[];
/** Return values for the OggFLAC__SeekableStreamDecoder seek callback.
*/
typedef enum {
OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK,
/**< The seek was OK and decoding can continue. */
OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR
/**< An unrecoverable error occurred. The decoder will return from the process call. */
} OggFLAC__SeekableStreamDecoderSeekStatus;
/** Maps a OggFLAC__SeekableStreamDecoderSeekStatus to a C string.
*
* Using a OggFLAC__SeekableStreamDecoderSeekStatus as the index to this array
* will give the string equivalent. The contents should not be modified.
*/
extern OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderSeekStatusString[];
/** Return values for the OggFLAC__SeekableStreamDecoder tell callback.
*/
typedef enum {
OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK,
/**< The tell was OK and decoding can continue. */
OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR
/**< An unrecoverable error occurred. The decoder will return from the process call. */
} OggFLAC__SeekableStreamDecoderTellStatus;
/** Maps a OggFLAC__SeekableStreamDecoderTellStatus to a C string.
*
* Using a OggFLAC__SeekableStreamDecoderTellStatus as the index to this array
* will give the string equivalent. The contents should not be modified.
*/
extern OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderTellStatusString[];
/** Return values for the OggFLAC__SeekableStreamDecoder length callback.
*/
typedef enum {
OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK,
/**< The length call was OK and decoding can continue. */
OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR
/**< An unrecoverable error occurred. The decoder will return from the process call. */
} OggFLAC__SeekableStreamDecoderLengthStatus;
/** Maps a OggFLAC__SeekableStreamDecoderLengthStatus to a C string.
*
* Using a OggFLAC__SeekableStreamDecoderLengthStatus as the index to this array
* will give the string equivalent. The contents should not be modified.
*/
extern OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderLengthStatusString[];
/***********************************************************************
*
* class OggFLAC__SeekableStreamDecoder : public FLAC__StreamDecoder
@ -147,7 +231,7 @@ typedef struct {
* \retval FLAC__SeekableStreamDecoderReadStatus
* The callee's return status.
*/
typedef FLAC__SeekableStreamDecoderReadStatus (*OggFLAC__SeekableStreamDecoderReadCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
typedef OggFLAC__SeekableStreamDecoderReadStatus (*OggFLAC__SeekableStreamDecoderReadCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
/** Signature for the seek callback.
* See OggFLAC__seekable_stream_decoder_set_seek_callback() for more info.
@ -160,7 +244,7 @@ typedef FLAC__SeekableStreamDecoderReadStatus (*OggFLAC__SeekableStreamDecoderRe
* \retval FLAC__SeekableStreamDecoderSeekStatus
* The callee's return status.
*/
typedef FLAC__SeekableStreamDecoderSeekStatus (*OggFLAC__SeekableStreamDecoderSeekCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
typedef OggFLAC__SeekableStreamDecoderSeekStatus (*OggFLAC__SeekableStreamDecoderSeekCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
/** Signature for the tell callback.
* See OggFLAC__seekable_stream_decoder_set_tell_callback() for more info.
@ -173,7 +257,7 @@ typedef FLAC__SeekableStreamDecoderSeekStatus (*OggFLAC__SeekableStreamDecoderSe
* \retval FLAC__SeekableStreamDecoderTellStatus
* The callee's return status.
*/
typedef FLAC__SeekableStreamDecoderTellStatus (*OggFLAC__SeekableStreamDecoderTellCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
typedef OggFLAC__SeekableStreamDecoderTellStatus (*OggFLAC__SeekableStreamDecoderTellCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
/** Signature for the length callback.
* See OggFLAC__seekable_stream_decoder_set_length_callback() for more info.
@ -186,7 +270,7 @@ typedef FLAC__SeekableStreamDecoderTellStatus (*OggFLAC__SeekableStreamDecoderTe
* \retval FLAC__SeekableStreamDecoderLengthStatus
* The callee's return status.
*/
typedef FLAC__SeekableStreamDecoderLengthStatus (*OggFLAC__SeekableStreamDecoderLengthCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
typedef OggFLAC__SeekableStreamDecoderLengthStatus (*OggFLAC__SeekableStreamDecoderLengthCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
/** Signature for the EOF callback.
* See OggFLAC__seekable_stream_decoder_set_eof_callback() for more info.
@ -550,22 +634,22 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore_all(
*/
OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_get_state(const OggFLAC__SeekableStreamDecoder *decoder);
/** Get the state of the underlying FLAC seekable stream decoder.
/** Get the state of the underlying stream decoder.
* Useful when the seekable stream decoder state is
* \c OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR.
* \c OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR.
*
* \param decoder A decoder instance to query.
* \assert
* \code decoder != NULL \endcode
* \retval FLAC__SeekableStreamDecoderState
* The FLAC seekable stream decoder state.
* \retval OggFLAC__StreamDecoderState
* The stream decoder state.
*/
OggFLAC_API FLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state(const OggFLAC__SeekableStreamDecoder *decoder);
OggFLAC_API OggFLAC__StreamDecoderState OggFLAC__seekable_stream_decoder_get_stream_decoder_state(const OggFLAC__SeekableStreamDecoder *decoder);
/** Get the state of the underlying FLAC seekable stream decoder's stream decoder.
/** Get the state of the underlying stream decoder's FLAC stream decoder.
* Useful when the seekable stream decoder state is
* \c OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR and the
* FLAC seekable stream decoder state is \c FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR
* \c OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR and the
* stream decoder state is \c OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR
*
* \param decoder A decoder instance to query.
* \assert
@ -577,8 +661,8 @@ OggFLAC_API FLAC__StreamDecoderState OggFLAC__seekable_stream_decoder_get_FLAC_s
/** Get the current decoder state as a C string.
* This version automatically resolves
* \c OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR
* by getting the FLAC seekable stream decoder's state.
* \c OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR
* by getting the stream decoder's state.
*
* \param decoder A decoder instance to query.
* \assert
@ -654,6 +738,8 @@ OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_sample_rate(const OggF
*/
OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_blocksize(const OggFLAC__SeekableStreamDecoder *decoder);
#if 0
@@@@@@ this can never be made to work without writing a custom Ogg decoder; remove for release
/** Returns the decoder's current read position within the stream.
* This is inherited from FLAC__SeekableStreamDecoder; see
* FLAC__seekable_stream_decoder_get_decode_position().
@ -667,7 +753,9 @@ OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_blocksize(const OggFLA
* \c true if successful, \c false if there was an error from
* the 'tell' callback.
*/
/*@@@@@@ probably does not work... is it used? */
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_get_decode_position(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *position);
#endif
/** Initialize the decoder instance.
* Should be called after OggFLAC__seekable_stream_decoder_new() and

View File

@ -123,10 +123,10 @@ namespace OggFLAC {
return OggFLAC::Decoder::SeekableStream::State(::OggFLAC__file_decoder_get_seekable_stream_decoder_state(decoder_));
}
FLAC::Decoder::SeekableStream::State File::get_FLAC_seekable_stream_decoder_state() const
OggFLAC::Decoder::Stream::State File::get_stream_decoder_state() const
{
FLAC__ASSERT(is_valid());
return FLAC::Decoder::SeekableStream::State(::OggFLAC__file_decoder_get_FLAC_seekable_stream_decoder_state(decoder_));
return OggFLAC::Decoder::Stream::State(::OggFLAC__file_decoder_get_stream_decoder_state(decoder_));
}
FLAC::Decoder::Stream::State File::get_FLAC_stream_decoder_state() const

View File

@ -111,10 +111,10 @@ namespace OggFLAC {
return State(::OggFLAC__seekable_stream_decoder_get_state(decoder_));
}
FLAC::Decoder::SeekableStream::State SeekableStream::get_FLAC_seekable_stream_decoder_state() const
OggFLAC::Decoder::Stream::State SeekableStream::get_stream_decoder_state() const
{
FLAC__ASSERT(is_valid());
return FLAC::Decoder::SeekableStream::State(::OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state(decoder_));
return OggFLAC::Decoder::Stream::State(::OggFLAC__seekable_stream_decoder_get_stream_decoder_state(decoder_));
}
FLAC::Decoder::Stream::State SeekableStream::get_FLAC_stream_decoder_state() const
@ -216,7 +216,7 @@ namespace OggFLAC {
return (bool)::OggFLAC__seekable_stream_decoder_seek_absolute(decoder_, sample);
}
::FLAC__SeekableStreamDecoderReadStatus SeekableStream::read_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
::OggFLAC__SeekableStreamDecoderReadStatus SeekableStream::read_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
{
(void) decoder;
FLAC__ASSERT(0 != client_data);
@ -225,7 +225,7 @@ namespace OggFLAC {
return instance->read_callback(buffer, bytes);
}
::FLAC__SeekableStreamDecoderSeekStatus SeekableStream::seek_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
::OggFLAC__SeekableStreamDecoderSeekStatus SeekableStream::seek_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
{
(void) decoder;
FLAC__ASSERT(0 != client_data);
@ -234,7 +234,7 @@ namespace OggFLAC {
return instance->seek_callback(absolute_byte_offset);
}
::FLAC__SeekableStreamDecoderTellStatus SeekableStream::tell_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
::OggFLAC__SeekableStreamDecoderTellStatus SeekableStream::tell_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
{
(void) decoder;
FLAC__ASSERT(0 != client_data);
@ -243,7 +243,7 @@ namespace OggFLAC {
return instance->tell_callback(absolute_byte_offset);
}
::FLAC__SeekableStreamDecoderLengthStatus SeekableStream::length_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
::OggFLAC__SeekableStreamDecoderLengthStatus SeekableStream::length_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
{
(void) decoder;
FLAC__ASSERT(0 != client_data);

View File

@ -52,10 +52,10 @@
static void set_defaults_(OggFLAC__FileDecoder *decoder);
static FILE *get_binary_stdin_();
static FLAC__SeekableStreamDecoderReadStatus read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
static OggFLAC__SeekableStreamDecoderReadStatus read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
static OggFLAC__SeekableStreamDecoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
static OggFLAC__SeekableStreamDecoderTellStatus tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
static OggFLAC__SeekableStreamDecoderLengthStatus length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
static FLAC__bool eof_callback_(const OggFLAC__SeekableStreamDecoder *decoder, void *client_data);
static FLAC__StreamDecoderWriteStatus write_callback_(const OggFLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
static void metadata_callback_(const OggFLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
@ -392,11 +392,11 @@ OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__file_decoder_get_seekab
return OggFLAC__seekable_stream_decoder_get_state(decoder->private_->seekable_stream_decoder);
}
OggFLAC_API FLAC__SeekableStreamDecoderState OggFLAC__file_decoder_get_FLAC_seekable_stream_decoder_state(const OggFLAC__FileDecoder *decoder)
OggFLAC_API OggFLAC__StreamDecoderState OggFLAC__file_decoder_get_stream_decoder_state(const OggFLAC__FileDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
return OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state(decoder->private_->seekable_stream_decoder);
return OggFLAC__seekable_stream_decoder_get_stream_decoder_state(decoder->private_->seekable_stream_decoder);
}
OggFLAC_API FLAC__StreamDecoderState OggFLAC__file_decoder_get_FLAC_stream_decoder_state(const OggFLAC__FileDecoder *decoder)
@ -456,12 +456,15 @@ OggFLAC_API unsigned OggFLAC__file_decoder_get_blocksize(const OggFLAC__FileDeco
return OggFLAC__seekable_stream_decoder_get_blocksize(decoder->private_->seekable_stream_decoder);
}
#if 0
@@@@@@ this can never be made to work without writing a custom Ogg decoder; remove for release
OggFLAC_API FLAC__bool OggFLAC__file_decoder_get_decode_position(const OggFLAC__FileDecoder *decoder, FLAC__uint64 *position)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
return OggFLAC__seekable_stream_decoder_get_decode_position(decoder->private_->seekable_stream_decoder, position);
}
#endif
OggFLAC_API FLAC__bool OggFLAC__file_decoder_process_single(OggFLAC__FileDecoder *decoder)
{
@ -581,7 +584,7 @@ FILE *get_binary_stdin_()
return stdin;
}
FLAC__SeekableStreamDecoderReadStatus read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
OggFLAC__SeekableStreamDecoderReadStatus read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
{
OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
(void)decoder;
@ -589,52 +592,52 @@ FLAC__SeekableStreamDecoderReadStatus read_callback_(const OggFLAC__SeekableStre
if(*bytes > 0) {
*bytes = (unsigned)fread(buffer, sizeof(FLAC__byte), *bytes, file_decoder->private_->file);
if(ferror(file_decoder->private_->file)) {
return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
}
else {
return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
}
}
else
return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
}
FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
OggFLAC__SeekableStreamDecoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
{
OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
(void)decoder;
if(fseek(file_decoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
else
return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
}
FLAC__SeekableStreamDecoderTellStatus tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
OggFLAC__SeekableStreamDecoderTellStatus tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
{
OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
long pos;
(void)decoder;
if((pos = ftell(file_decoder->private_->file)) < 0)
return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
else {
*absolute_byte_offset = (FLAC__uint64)pos;
return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
}
}
FLAC__SeekableStreamDecoderLengthStatus length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
OggFLAC__SeekableStreamDecoderLengthStatus length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
{
OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
struct stat filestats;
(void)decoder;
if(0 == file_decoder->private_->filename || stat(file_decoder->private_->filename, &filestats) != 0)
return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
else {
*stream_length = (FLAC__uint64)filestats.st_size;
return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
}
}

View File

@ -36,6 +36,7 @@
#include "private/ogg_decoder_aspect.h"
typedef struct OggFLAC__SeekableStreamDecoderProtected {
FLAC__bool md5_checking; /* if true, generate MD5 signature of decoded data and compare against signature in the STREAMINFO metadata block */
OggFLAC__SeekableStreamDecoderState state;
OggFLAC__OggDecoderAspect ogg_decoder_aspect;
} OggFLAC__SeekableStreamDecoderProtected;

View File

@ -29,9 +29,13 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h> /* for calloc() */
#include <string.h> /* for memcpy()/memcmp() */
#include "FLAC/assert.h"
#include "protected/seekable_stream_decoder.h"
#include "protected/stream_decoder.h"
#include "../libFLAC/include/private/md5.h" /* @@@@@@ ugly hack, but how else to do? we need to reuse the md5 code but don't want to expose it */
/***********************************************************************
*
@ -40,16 +44,11 @@
***********************************************************************/
static void set_defaults_(OggFLAC__SeekableStreamDecoder *decoder);
static FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
static FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data);
static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
static void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
static void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
static OggFLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
static FLAC__StreamDecoderReadStatus read_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
static FLAC__StreamDecoderWriteStatus write_callback_(const OggFLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
static void metadata_callback_(const OggFLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
static void error_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
static FLAC__bool seek_to_absolute_sample_(OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample);
/***********************************************************************
*
@ -67,7 +66,19 @@ typedef struct OggFLAC__SeekableStreamDecoderPrivate {
OggFLAC__SeekableStreamDecoderMetadataCallback metadata_callback;
OggFLAC__SeekableStreamDecoderErrorCallback error_callback;
void *client_data;
FLAC__SeekableStreamDecoder *FLAC_seekable_stream_decoder;
OggFLAC__StreamDecoder *stream_decoder;
FLAC__bool do_md5_checking; /* initially gets protected_->md5_checking but is turned off after a seek */
struct MD5Context md5context;
FLAC__byte stored_md5sum[16]; /* this is what is stored in the metadata */
FLAC__byte computed_md5sum[16]; /* this is the sum we computed from the decoded data */
/* the rest of these are only used for seeking: */
FLAC__StreamMetadata_StreamInfo stream_info; /* we keep this around so we can figure out how to seek quickly */
const FLAC__StreamMetadata_SeekTable *seek_table; /* we hold a pointer to the stream decoder's seek table for the same reason */
/* Since we always want to see the STREAMINFO and SEEK_TABLE blocks at this level, we need some extra flags to keep track of whether they should be passed on up through the metadata_callback */
FLAC__bool ignore_stream_info_block;
FLAC__bool ignore_seek_table_block;
FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */
FLAC__uint64 target_sample;
} OggFLAC__SeekableStreamDecoderPrivate;
/***********************************************************************
@ -78,26 +89,50 @@ typedef struct OggFLAC__SeekableStreamDecoderPrivate {
OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderStateString[] = {
"OggFLAC__SEEKABLE_STREAM_DECODER_OK",
"OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING",
"OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM",
"OggFLAC__SEEKABLE_STREAM_DECODER_OGG_ERROR",
"OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR",
"OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR",
"OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
"OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR",
"OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR",
"OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR",
"OggFLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED",
"OggFLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK",
"OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED"
};
OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderReadStatusString[] = {
"OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK",
"OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR"
};
OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderSeekStatusString[] = {
"OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK",
"OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR"
};
OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderTellStatusString[] = {
"OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK",
"OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR"
};
OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderLengthStatusString[] = {
"OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK",
"OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR"
};
/***********************************************************************
*
* Class constructor/destructor
*
***********************************************************************/
OggFLAC_API OggFLAC__SeekableStreamDecoder *OggFLAC__seekable_stream_decoder_new()
{
OggFLAC__SeekableStreamDecoder *decoder;
FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
decoder = (OggFLAC__SeekableStreamDecoder*)calloc(1, sizeof(OggFLAC__SeekableStreamDecoder));
if(decoder == 0) {
return 0;
@ -116,8 +151,8 @@ OggFLAC_API OggFLAC__SeekableStreamDecoder *OggFLAC__seekable_stream_decoder_new
return 0;
}
decoder->private_->FLAC_seekable_stream_decoder = FLAC__seekable_stream_decoder_new();
if(0 == decoder->private_->FLAC_seekable_stream_decoder) {
decoder->private_->stream_decoder = OggFLAC__stream_decoder_new();
if(0 == decoder->private_->stream_decoder) {
free(decoder->private_);
free(decoder->protected_);
free(decoder);
@ -136,11 +171,11 @@ OggFLAC_API void OggFLAC__seekable_stream_decoder_delete(OggFLAC__SeekableStream
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->protected_);
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->private_->FLAC_seekable_stream_decoder);
FLAC__ASSERT(0 != decoder->private_->stream_decoder);
OggFLAC__seekable_stream_decoder_finish(decoder);
(void)OggFLAC__seekable_stream_decoder_finish(decoder);
FLAC__seekable_stream_decoder_delete(decoder->private_->FLAC_seekable_stream_decoder);
OggFLAC__stream_decoder_delete(decoder->private_->stream_decoder);
free(decoder->private_);
free(decoder->protected_);
@ -160,31 +195,46 @@ OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED;
if(0 == decoder->private_->read_callback || 0 == decoder->private_->seek_callback || 0 == decoder->private_->tell_callback || 0 == decoder->private_->length_callback || 0 == decoder->private_->eof_callback || 0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
if(0 == decoder->private_->read_callback || 0 == decoder->private_->seek_callback || 0 == decoder->private_->tell_callback || 0 == decoder->private_->length_callback || 0 == decoder->private_->eof_callback)
return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK;
if(!OggFLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect))
return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OGG_ERROR;
if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK;
FLAC__seekable_stream_decoder_set_read_callback(decoder->private_->FLAC_seekable_stream_decoder, read_callback_);
FLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->FLAC_seekable_stream_decoder, seek_callback_);
FLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->FLAC_seekable_stream_decoder, tell_callback_);
FLAC__seekable_stream_decoder_set_length_callback(decoder->private_->FLAC_seekable_stream_decoder, length_callback_);
FLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->FLAC_seekable_stream_decoder, eof_callback_);
FLAC__seekable_stream_decoder_set_write_callback(decoder->private_->FLAC_seekable_stream_decoder, write_callback_);
FLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->FLAC_seekable_stream_decoder, metadata_callback_);
FLAC__seekable_stream_decoder_set_error_callback(decoder->private_->FLAC_seekable_stream_decoder, error_callback_);
FLAC__seekable_stream_decoder_set_client_data(decoder->private_->FLAC_seekable_stream_decoder, decoder);
decoder->private_->seek_table = 0;
if(FLAC__seekable_stream_decoder_init(decoder->private_->FLAC_seekable_stream_decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK)
return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
/* We initialize the MD5Context even though we may never use it. This is
* because md5 checking may be turned on to start and then turned off if a
* seek occurs. So we always init the context here and finalize it in
* OggFLAC__seekable_stream_decoder_finish() to make sure things are always
* cleaned up properly.
*/
MD5Init(&decoder->private_->md5context);
OggFLAC__stream_decoder_set_read_callback(decoder->private_->stream_decoder, read_callback_);
OggFLAC__stream_decoder_set_write_callback(decoder->private_->stream_decoder, write_callback_);
OggFLAC__stream_decoder_set_metadata_callback(decoder->private_->stream_decoder, metadata_callback_);
OggFLAC__stream_decoder_set_error_callback(decoder->private_->stream_decoder, error_callback_);
OggFLAC__stream_decoder_set_client_data(decoder->private_->stream_decoder, decoder);
/* We always want to see these blocks. Whether or not we pass them up
* through the metadata callback will be determined by flags set in our
* implementation of ..._set_metadata_respond/ignore...()
*/
OggFLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_STREAMINFO);
OggFLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_SEEKTABLE);
if(OggFLAC__stream_decoder_init(decoder->private_->stream_decoder) != OggFLAC__STREAM_DECODER_OK)
return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_finish(OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__bool ok;
FLAC__bool md5_failed = false;
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
@ -193,27 +243,35 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_finish(OggFLAC__Seekable
if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return true;
FLAC__ASSERT(0 != decoder->private_->FLAC_seekable_stream_decoder);
FLAC__ASSERT(0 != decoder->private_->stream_decoder);
ok = FLAC__seekable_stream_decoder_finish(decoder->private_->FLAC_seekable_stream_decoder);
/* see the comment in OggFLAC__seekable_stream_decoder_init() as to why we
* always call MD5Final()
*/
MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context);
OggFLAC__ogg_decoder_aspect_finish(&decoder->protected_->ogg_decoder_aspect);
OggFLAC__stream_decoder_finish(decoder->private_->stream_decoder);
if(decoder->private_->do_md5_checking) {
if(memcmp(decoder->private_->stored_md5sum, decoder->private_->computed_md5sum, 16))
md5_failed = true;
}
set_defaults_(decoder);
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED;
return ok;
return !md5_failed;
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_md5_checking(OggFLAC__SeekableStreamDecoder *decoder, FLAC__bool value)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return false;
return FLAC__seekable_stream_decoder_set_md5_checking(decoder->private_->FLAC_seekable_stream_decoder, value);
decoder->protected_->md5_checking = value;
return true;
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_read_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderReadCallback value)
@ -331,9 +389,14 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_respond(Ogg
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
FLAC__ASSERT(0 != decoder->private_->stream_decoder);
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return false;
return FLAC__seekable_stream_decoder_set_metadata_respond(decoder->private_->FLAC_seekable_stream_decoder, type);
if(type == FLAC__METADATA_TYPE_STREAMINFO)
decoder->private_->ignore_stream_info_block = false;
else if(type == FLAC__METADATA_TYPE_SEEKTABLE)
decoder->private_->ignore_seek_table_block = false;
return OggFLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, type);
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_respond_application(OggFLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4])
@ -341,9 +404,10 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_respond_app
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
FLAC__ASSERT(0 != decoder->private_->stream_decoder);
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return false;
return FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder->private_->FLAC_seekable_stream_decoder, id);
return OggFLAC__stream_decoder_set_metadata_respond_application(decoder->private_->stream_decoder, id);
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_respond_all(OggFLAC__SeekableStreamDecoder *decoder)
@ -351,9 +415,12 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_respond_all
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
FLAC__ASSERT(0 != decoder->private_->stream_decoder);
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return false;
return FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder->private_->FLAC_seekable_stream_decoder);
decoder->private_->ignore_stream_info_block = false;
decoder->private_->ignore_seek_table_block = false;
return OggFLAC__stream_decoder_set_metadata_respond_all(decoder->private_->stream_decoder);
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore(OggFLAC__SeekableStreamDecoder *decoder, FLAC__MetadataType type)
@ -361,9 +428,19 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore(OggF
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
FLAC__ASSERT(0 != decoder->private_->stream_decoder);
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return false;
return FLAC__seekable_stream_decoder_set_metadata_ignore(decoder->private_->FLAC_seekable_stream_decoder, type);
if(type == FLAC__METADATA_TYPE_STREAMINFO) {
decoder->private_->ignore_stream_info_block = true;
return true;
}
else if(type == FLAC__METADATA_TYPE_SEEKTABLE) {
decoder->private_->ignore_seek_table_block = true;
return true;
}
else
return OggFLAC__stream_decoder_set_metadata_ignore(decoder->private_->stream_decoder, type);
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore_application(OggFLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4])
@ -371,9 +448,10 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore_appl
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
FLAC__ASSERT(0 != decoder->private_->stream_decoder);
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return false;
return FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder->private_->FLAC_seekable_stream_decoder, id);
return OggFLAC__stream_decoder_set_metadata_ignore_application(decoder->private_->stream_decoder, id);
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore_all(OggFLAC__SeekableStreamDecoder *decoder)
@ -381,9 +459,15 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore_all(
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
FLAC__ASSERT(0 != decoder->private_->stream_decoder);
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return false;
return FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder->private_->FLAC_seekable_stream_decoder);
decoder->private_->ignore_stream_info_block = true;
decoder->private_->ignore_seek_table_block = true;
return
OggFLAC__stream_decoder_set_metadata_ignore_all(decoder->private_->stream_decoder) &&
OggFLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_STREAMINFO) &&
OggFLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_SEEKTABLE);
}
OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_get_state(const OggFLAC__SeekableStreamDecoder *decoder)
@ -393,76 +477,85 @@ OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder
return decoder->protected_->state;
}
OggFLAC_API FLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state(const OggFLAC__SeekableStreamDecoder *decoder)
OggFLAC_API OggFLAC__StreamDecoderState OggFLAC__seekable_stream_decoder_get_stream_decoder_state(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
return FLAC__seekable_stream_decoder_get_state(decoder->private_->FLAC_seekable_stream_decoder);
return OggFLAC__stream_decoder_get_state(decoder->private_->stream_decoder);
}
OggFLAC_API FLAC__StreamDecoderState OggFLAC__seekable_stream_decoder_get_FLAC_stream_decoder_state(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
return FLAC__seekable_stream_decoder_get_stream_decoder_state(decoder->private_->FLAC_seekable_stream_decoder);
return OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(decoder->private_->stream_decoder);
}
OggFLAC_API const char *OggFLAC__seekable_stream_decoder_get_resolved_state_string(const OggFLAC__SeekableStreamDecoder *decoder)
{
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR)
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR)
return OggFLAC__SeekableStreamDecoderStateString[decoder->protected_->state];
else
return FLAC__seekable_stream_decoder_get_resolved_state_string(decoder->private_->FLAC_seekable_stream_decoder);
return OggFLAC__stream_decoder_get_resolved_state_string(decoder->private_->stream_decoder);
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_get_md5_checking(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
return FLAC__seekable_stream_decoder_get_md5_checking(decoder->private_->FLAC_seekable_stream_decoder);
FLAC__ASSERT(0 != decoder->protected_);
return decoder->protected_->md5_checking;
}
OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_channels(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
return FLAC__seekable_stream_decoder_get_channels(decoder->private_->FLAC_seekable_stream_decoder);
return OggFLAC__stream_decoder_get_channels(decoder->private_->stream_decoder);
}
OggFLAC_API FLAC__ChannelAssignment OggFLAC__seekable_stream_decoder_get_channel_assignment(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
return FLAC__seekable_stream_decoder_get_channel_assignment(decoder->private_->FLAC_seekable_stream_decoder);
return OggFLAC__stream_decoder_get_channel_assignment(decoder->private_->stream_decoder);
}
OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_bits_per_sample(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
return FLAC__seekable_stream_decoder_get_bits_per_sample(decoder->private_->FLAC_seekable_stream_decoder);
return OggFLAC__stream_decoder_get_bits_per_sample(decoder->private_->stream_decoder);
}
OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_sample_rate(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
return FLAC__seekable_stream_decoder_get_sample_rate(decoder->private_->FLAC_seekable_stream_decoder);
return OggFLAC__stream_decoder_get_sample_rate(decoder->private_->stream_decoder);
}
OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_blocksize(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
return FLAC__seekable_stream_decoder_get_blocksize(decoder->private_->FLAC_seekable_stream_decoder);
return OggFLAC__stream_decoder_get_blocksize(decoder->private_->stream_decoder);
}
#if 0
@@@@@@ this can never be made to work without writing a custom Ogg decoder; remove for release
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_get_decode_position(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *position)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
return FLAC__seekable_stream_decoder_get_decode_position(decoder->private_->FLAC_seekable_stream_decoder, position);
FLAC__ASSERT(0 != position);
if(decoder->private_->tell_callback(decoder, position, decoder->private_->client_data) != OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK)
return false;
FLAC__ASSERT(*position >= OggFLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder));
*position -= OggFLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder);
return true;
}
#endif
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_flush(OggFLAC__SeekableStreamDecoder *decoder)
{
@ -470,10 +563,10 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_flush(OggFLAC__SeekableS
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
OggFLAC__ogg_decoder_aspect_flush(&decoder->protected_->ogg_decoder_aspect);
decoder->private_->do_md5_checking = false;
if(!FLAC__seekable_stream_decoder_flush(decoder->private_->FLAC_seekable_stream_decoder)) {
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
if(!OggFLAC__stream_decoder_flush(decoder->private_->stream_decoder)) {
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return false;
}
@ -489,15 +582,27 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_reset(OggFLAC__SeekableS
FLAC__ASSERT(0 != decoder->protected_);
if(!OggFLAC__seekable_stream_decoder_flush(decoder)) {
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return false;
}
if(!FLAC__seekable_stream_decoder_reset(decoder->private_->FLAC_seekable_stream_decoder)) {
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
if(!OggFLAC__stream_decoder_reset(decoder->private_->stream_decoder)) {
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return false;
}
decoder->private_->seek_table = 0;
decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
/* We initialize the MD5Context even though we may never use it. This is
* because md5 checking may be turned on to start and then turned off if a
* seek occurs. So we always init the context here and finalize it in
* OggFLAC__seekable_stream_decoder_finish() to make sure things are always
* cleaned up properly.
*/
MD5Init(&decoder->private_->md5context);
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
return true;
@ -508,7 +613,7 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_process_single(OggFLAC__
FLAC__bool ret;
FLAC__ASSERT(0 != decoder);
if(FLAC__seekable_stream_decoder_get_state(decoder->private_->FLAC_seekable_stream_decoder) == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
if(decoder->private_->stream_decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
@ -516,9 +621,9 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_process_single(OggFLAC__
FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK);
ret = FLAC__seekable_stream_decoder_process_single(decoder->private_->FLAC_seekable_stream_decoder);
ret = OggFLAC__stream_decoder_process_single(decoder->private_->stream_decoder);
if(!ret)
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return ret;
}
@ -528,7 +633,7 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_process_until_end_of_met
FLAC__bool ret;
FLAC__ASSERT(0 != decoder);
if(FLAC__seekable_stream_decoder_get_state(decoder->private_->FLAC_seekable_stream_decoder) == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
if(decoder->private_->stream_decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
@ -536,9 +641,9 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_process_until_end_of_met
FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK);
ret = FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder->private_->FLAC_seekable_stream_decoder);
ret = OggFLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder);
if(!ret)
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return ret;
}
@ -548,7 +653,7 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_process_until_end_of_str
FLAC__bool ret;
FLAC__ASSERT(0 != decoder);
if(FLAC__seekable_stream_decoder_get_state(decoder->private_->FLAC_seekable_stream_decoder) == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
if(decoder->private_->stream_decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
@ -556,28 +661,50 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_process_until_end_of_str
FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK);
ret = FLAC__seekable_stream_decoder_process_until_end_of_stream(decoder->private_->FLAC_seekable_stream_decoder);
ret = OggFLAC__stream_decoder_process_until_end_of_stream(decoder->private_->stream_decoder);
if(!ret)
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return ret;
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_seek_absolute(OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 sample)
{
FLAC__uint64 length;
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK || decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM);
if(!FLAC__seekable_stream_decoder_seek_absolute(decoder->private_->FLAC_seekable_stream_decoder, sample)) {
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING;
/* turn off md5 checking if a seek is attempted */
decoder->private_->do_md5_checking = false;
if(!OggFLAC__stream_decoder_reset(decoder->private_->stream_decoder)) {
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return false;
}
else {
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
return true;
/* get the file length */
if(decoder->private_->length_callback(decoder, &length, decoder->private_->client_data) != OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK) {
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
return false;
}
/* rewind */
if(decoder->private_->seek_callback(decoder, 0, decoder->private_->client_data) != OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) {
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
return false;
}
if(!OggFLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder)) {
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return false;
}
if(decoder->private_->stream_info.total_samples > 0 && sample >= decoder->private_->stream_info.total_samples) {
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
return false;
}
}
return seek_to_absolute_sample_(decoder, length, sample);
}
/***********************************************************************
*
@ -596,108 +723,207 @@ void set_defaults_(OggFLAC__SeekableStreamDecoder *decoder)
decoder->private_->metadata_callback = 0;
decoder->private_->error_callback = 0;
decoder->private_->client_data = 0;
OggFLAC__ogg_decoder_aspect_set_defaults(&decoder->protected_->ogg_decoder_aspect);
/* WATCHOUT: these should match the default behavior of OggFLAC__StreamDecoder */
decoder->private_->ignore_stream_info_block = false;
decoder->private_->ignore_seek_table_block = true;
decoder->protected_->md5_checking = false;
}
FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *unused, FLAC__byte buffer[], unsigned *bytes, void *client_data)
FLAC__StreamDecoderReadStatus read_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
{
OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
(void)unused;
switch(OggFLAC__ogg_decoder_aspect_read_callback_wrapper(&decoder->protected_->ogg_decoder_aspect, buffer, bytes, read_callback_proxy_, decoder, decoder->private_->client_data)) {
case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_OK:
return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
/* we don't really have a way to handle lost sync via read
* callback so we'll let it pass and let the underlying
* FLAC decoder catch the error
*/
case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC:
return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM:
return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT:
case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR:
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR;
return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR:
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
default:
FLAC__ASSERT(0);
/* double protection */
return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
OggFLAC__SeekableStreamDecoder *seekable_stream_decoder = (OggFLAC__SeekableStreamDecoder *)client_data;
(void)decoder;
if(seekable_stream_decoder->private_->eof_callback(seekable_stream_decoder, seekable_stream_decoder->private_->client_data)) {
*bytes = 0;
#if 0
@@@@@@ verify that this is not needed:
seekable_stream_decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
#endif
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
}
}
FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *unused, FLAC__uint64 absolute_byte_offset, void *client_data)
{
OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
(void)unused;
/* need to flush the Ogg state */
OggFLAC__ogg_decoder_aspect_flush(&decoder->protected_->ogg_decoder_aspect);
return decoder->private_->seek_callback(decoder, absolute_byte_offset, decoder->private_->client_data);
}
FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *unused, FLAC__uint64 *absolute_byte_offset, void *client_data)
{
OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
(void)unused;
return decoder->private_->tell_callback(decoder, absolute_byte_offset, decoder->private_->client_data);
}
FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *unused, FLAC__uint64 *stream_length, void *client_data)
{
OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
(void)unused;
return decoder->private_->length_callback(decoder, stream_length, decoder->private_->client_data);
}
FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *unused, void *client_data)
{
OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
(void)unused;
return decoder->private_->eof_callback(decoder, decoder->private_->client_data);
}
FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *unused, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
{
OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
(void)unused;
return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
}
void metadata_callback_(const FLAC__SeekableStreamDecoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
{
OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
(void)unused;
decoder->private_->metadata_callback(decoder, metadata, decoder->private_->client_data);
}
void error_callback_(const FLAC__SeekableStreamDecoder *unused, FLAC__StreamDecoderErrorStatus status, void *client_data)
{
OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
(void)unused;
decoder->private_->error_callback(decoder, status, decoder->private_->client_data);
}
OggFLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
{
OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)void_decoder;
switch(decoder->private_->read_callback(decoder, buffer, bytes, client_data)) {
case FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK:
if (*bytes == 0)
return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM;
else if(*bytes > 0) {
if(seekable_stream_decoder->private_->read_callback(seekable_stream_decoder, buffer, bytes, seekable_stream_decoder->private_->client_data) != OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK) {
seekable_stream_decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR;
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
}
if(*bytes == 0) {
if(seekable_stream_decoder->private_->eof_callback(seekable_stream_decoder, seekable_stream_decoder->private_->client_data)) {
#if 0
@@@@@@ verify that this is not needed:
seekable_stream_decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
#endif
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
}
else
return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_OK;
case FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR:
return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
default:
/* double protection: */
FLAC__ASSERT(0);
return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
}
else {
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
}
}
else
return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
}
FLAC__StreamDecoderWriteStatus write_callback_(const OggFLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
{
OggFLAC__SeekableStreamDecoder *seekable_stream_decoder = (OggFLAC__SeekableStreamDecoder *)client_data;
(void)decoder;
if(seekable_stream_decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
FLAC__uint64 this_frame_sample = frame->header.number.sample_number;
FLAC__uint64 next_frame_sample = this_frame_sample + (FLAC__uint64)frame->header.blocksize;
FLAC__uint64 target_sample = seekable_stream_decoder->private_->target_sample;
FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
seekable_stream_decoder->private_->last_frame = *frame; /* save the frame */
if(this_frame_sample <= target_sample && target_sample < next_frame_sample) { /* we hit our target frame */
unsigned delta = (unsigned)(target_sample - this_frame_sample);
/* kick out of seek mode */
seekable_stream_decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
/* shift out the samples before target_sample */
if(delta > 0) {
unsigned channel;
const FLAC__int32 *newbuffer[FLAC__MAX_CHANNELS];
for(channel = 0; channel < frame->header.channels; channel++)
newbuffer[channel] = buffer[channel] + delta;
seekable_stream_decoder->private_->last_frame.header.blocksize -= delta;
seekable_stream_decoder->private_->last_frame.header.number.sample_number += (FLAC__uint64)delta;
/* write the relevant samples */
return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, &seekable_stream_decoder->private_->last_frame, newbuffer, seekable_stream_decoder->private_->client_data);
}
else {
/* write the relevant samples */
return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, frame, buffer, seekable_stream_decoder->private_->client_data);
}
}
else {
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
}
else {
if(seekable_stream_decoder->private_->do_md5_checking) {
if(!FLAC__MD5Accumulate(&seekable_stream_decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8))
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, frame, buffer, seekable_stream_decoder->private_->client_data);
}
}
void metadata_callback_(const OggFLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
{
OggFLAC__SeekableStreamDecoder *seekable_stream_decoder = (OggFLAC__SeekableStreamDecoder *)client_data;
(void)decoder;
if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
seekable_stream_decoder->private_->stream_info = metadata->data.stream_info;
/* save the MD5 signature for comparison later */
memcpy(seekable_stream_decoder->private_->stored_md5sum, metadata->data.stream_info.md5sum, 16);
if(0 == memcmp(seekable_stream_decoder->private_->stored_md5sum, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16))
seekable_stream_decoder->private_->do_md5_checking = false;
}
else if(metadata->type == FLAC__METADATA_TYPE_SEEKTABLE) {
seekable_stream_decoder->private_->seek_table = &metadata->data.seek_table;
}
if(seekable_stream_decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
FLAC__bool ignore_block = false;
if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO && seekable_stream_decoder->private_->ignore_stream_info_block)
ignore_block = true;
else if(metadata->type == FLAC__METADATA_TYPE_SEEKTABLE && seekable_stream_decoder->private_->ignore_seek_table_block)
ignore_block = true;
if(!ignore_block)
seekable_stream_decoder->private_->metadata_callback(seekable_stream_decoder, metadata, seekable_stream_decoder->private_->client_data);
}
}
void error_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
{
OggFLAC__SeekableStreamDecoder *seekable_stream_decoder = (OggFLAC__SeekableStreamDecoder *)client_data;
(void)decoder;
if(seekable_stream_decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING)
seekable_stream_decoder->private_->error_callback(seekable_stream_decoder, status, seekable_stream_decoder->private_->client_data);
}
FLAC__bool seek_to_absolute_sample_(OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample)
{
FLAC__uint64 left_pos = 0, right_pos = stream_length;
FLAC__uint64 left_sample = 0, right_sample = decoder->private_->stream_info.total_samples;
unsigned iteration = 0;
/* In the first iterations, we will calculate the target byte position
* by the distance from the target sample to left_sample and
* right_sample. After that, we will switch to binary search.
*/
static const unsigned BINARY_SEARCH_AFTER_ITERATION = 2;
/* We will switch to a linear search once our current sample is less
* that this number of samples ahead of the target sample
*/
static const FLAC__uint64 LINEAR_SEARCH_WITHIN_SAMPLES = FLAC__MAX_BLOCK_SIZE * 2;
/* If the total number of samples is unknown, use a large value and
* increase 'iteration' to force binary search immediately.
*/
if(right_sample == 0) {
right_sample = (FLAC__uint64)(-1);
iteration = BINARY_SEARCH_AFTER_ITERATION;
}
decoder->private_->target_sample = target_sample;
for( ; ; iteration++) {
if(!OggFLAC__stream_decoder_process_single(decoder->private_->stream_decoder)) {
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
return false;
}
/* our write callback will change the state when it gets to the target frame */
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
break;
}
else {
const FLAC__uint64 this_frame_sample = decoder->private_->last_frame.header.number.sample_number;
FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
if (this_frame_sample > target_sample || target_sample - this_frame_sample > LINEAR_SEARCH_WITHIN_SAMPLES) {
FLAC__uint64 pos;
if (iteration >= BINARY_SEARCH_AFTER_ITERATION)
pos = (right_pos + left_pos) / 2;
else
pos = (FLAC__uint64)((double)(target_sample - left_sample) / (double)(right_pos - left_pos));
if (this_frame_sample <= target_sample) {
/* The 'equal' case should not happen, since
* OggFLAC__stream_decoder_process_single()
* should recognize that it has hit the
* target sample and we would exit through
* the 'break' above.
*/
FLAC__ASSERT(this_frame_sample != target_sample);
left_sample = this_frame_sample;
left_pos = pos;
}
else if(this_frame_sample > target_sample) {
right_sample = this_frame_sample;
right_pos = pos;
}
/* physical seek */
if(decoder->private_->seek_callback(decoder, (FLAC__uint64)pos, decoder->private_->client_data) != OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) {
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
return false;
}
if(!OggFLAC__stream_decoder_flush(decoder->private_->stream_decoder)) {
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return false;
}
}
}
}
return true;
}

View File

@ -802,10 +802,10 @@ public:
~SeekableStreamDecoder() { }
// from OggFLAC::Decoder::SeekableStream
::FLAC__SeekableStreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes);
::FLAC__SeekableStreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset);
::FLAC__SeekableStreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset);
::FLAC__SeekableStreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length);
::OggFLAC__SeekableStreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes);
::OggFLAC__SeekableStreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset);
::OggFLAC__SeekableStreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset);
::OggFLAC__SeekableStreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length);
bool eof_callback();
::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
void metadata_callback(const ::FLAC__StreamMetadata *metadata);
@ -816,56 +816,56 @@ public:
bool test_respond();
};
::FLAC__SeekableStreamDecoderReadStatus SeekableStreamDecoder::read_callback(FLAC__byte buffer[], unsigned *bytes)
::OggFLAC__SeekableStreamDecoderReadStatus SeekableStreamDecoder::read_callback(FLAC__byte buffer[], unsigned *bytes)
{
switch(common_read_callback_(buffer, bytes)) {
case ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE:
case ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM:
return ::FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
return ::OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
case ::FLAC__STREAM_DECODER_READ_STATUS_ABORT:
return ::FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
return ::OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
default:
FLAC__ASSERT(0);
return ::FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
return ::OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
}
}
::FLAC__SeekableStreamDecoderSeekStatus SeekableStreamDecoder::seek_callback(FLAC__uint64 absolute_byte_offset)
::OggFLAC__SeekableStreamDecoderSeekStatus SeekableStreamDecoder::seek_callback(FLAC__uint64 absolute_byte_offset)
{
if(error_occurred_)
return ::FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
return ::OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
if(::fseek(file_, (long)absolute_byte_offset, SEEK_SET) < 0) {
error_occurred_ = true;
return ::FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
return ::OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
}
return ::FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
return ::OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
}
::FLAC__SeekableStreamDecoderTellStatus SeekableStreamDecoder::tell_callback(FLAC__uint64 *absolute_byte_offset)
::OggFLAC__SeekableStreamDecoderTellStatus SeekableStreamDecoder::tell_callback(FLAC__uint64 *absolute_byte_offset)
{
if(error_occurred_)
return ::FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
return ::OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
long offset = ::ftell(file_);
*absolute_byte_offset = (FLAC__uint64)offset;
if(offset < 0) {
error_occurred_ = true;
return ::FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
return ::OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
}
return ::FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
return ::OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
}
::FLAC__SeekableStreamDecoderLengthStatus SeekableStreamDecoder::length_callback(FLAC__uint64 *stream_length)
::OggFLAC__SeekableStreamDecoderLengthStatus SeekableStreamDecoder::length_callback(FLAC__uint64 *stream_length)
{
if(error_occurred_)
return ::FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
return ::OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
*stream_length = (FLAC__uint64)oggflacfilesize_;
return ::FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
return ::OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
}
bool SeekableStreamDecoder::eof_callback()
@ -903,10 +903,10 @@ bool SeekableStreamDecoder::die(const char *msg) const
printf("FAILED");
printf(", state = %u (%s)\n", (unsigned)((::OggFLAC__SeekableStreamDecoderState)state), state.as_cstring());
if(state == ::OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR) {
FLAC::Decoder::SeekableStream::State state_ = get_FLAC_seekable_stream_decoder_state();
printf(" FLAC seekable stream decoder state = %u (%s)\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state_), state_.as_cstring());
if(state_ == ::FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
if(state == ::OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
OggFLAC::Decoder::Stream::State state_ = get_stream_decoder_state();
printf(" stream decoder state = %u (%s)\n", (unsigned)((::OggFLAC__StreamDecoderState)state_), state_.as_cstring());
if(state_ == ::OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR) {
FLAC::Decoder::Stream::State state__ = get_FLAC_stream_decoder_state();
printf(" FLAC stream decoder state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state__), state__.as_cstring());
}
@ -1046,9 +1046,9 @@ static bool test_seekable_stream_decoder()
OggFLAC::Decoder::SeekableStream::State state = decoder->get_state();
printf("returned state = %u (%s)... OK\n", (unsigned)((::OggFLAC__SeekableStreamDecoderState)state), state.as_cstring());
printf("testing get_FLAC_seekable_stream_decoder_state()... ");
FLAC::Decoder::SeekableStream::State state_ = decoder->get_FLAC_seekable_stream_decoder_state();
printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state_), state_.as_cstring());
printf("testing get_stream_decoder_state()... ");
OggFLAC::Decoder::Stream::State state_ = decoder->get_stream_decoder_state();
printf("returned state = %u (%s)... OK\n", (unsigned)((::OggFLAC__StreamDecoderState)state_), state_.as_cstring());
printf("testing get_FLAC_stream_decoder_state()... ");
FLAC::Decoder::Stream::State state__ = decoder->get_FLAC_stream_decoder_state();
@ -1575,10 +1575,10 @@ bool FileDecoder::die(const char *msg) const
if(state == ::OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR) {
OggFLAC::Decoder::SeekableStream::State state_ = get_seekable_stream_decoder_state();
printf(" seekable stream decoder state = %u (%s)\n", (unsigned)((::OggFLAC__SeekableStreamDecoderState)state_), state_.as_cstring());
if(state_ == ::OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR) {
FLAC::Decoder::SeekableStream::State state__ = get_FLAC_seekable_stream_decoder_state();
printf(" FLAC seekable stream decoder state = %u (%s)\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state__), state__.as_cstring());
if(state__ == ::FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
if(state_ == ::OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
OggFLAC::Decoder::Stream::State state__ = get_stream_decoder_state();
printf(" stream decoder state = %u (%s)\n", (unsigned)((::OggFLAC__StreamDecoderState)state__), state__.as_cstring());
if(state__ == ::OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR) {
FLAC::Decoder::Stream::State state___ = get_FLAC_stream_decoder_state();
printf(" FLAC stream decoder state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state___), state___.as_cstring());
}
@ -1730,9 +1730,9 @@ static bool test_file_decoder()
OggFLAC::Decoder::SeekableStream::State state_ = decoder->get_seekable_stream_decoder_state();
printf("returned state = %u (%s)... OK\n", (unsigned)((::OggFLAC__SeekableStreamDecoderState)state_), state_.as_cstring());
printf("testing get_FLAC_seekable_stream_decoder_state()... ");
FLAC::Decoder::SeekableStream::State state__ = decoder->get_FLAC_seekable_stream_decoder_state();
printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state__), state__.as_cstring());
printf("testing get_stream_decoder_state()... ");
OggFLAC::Decoder::Stream::State state__ = decoder->get_stream_decoder_state();
printf("returned state = %u (%s)... OK\n", (unsigned)((::OggFLAC__StreamDecoderState)state__), state__.as_cstring());
printf("testing get_FLAC_stream_decoder_state()... ");
FLAC::Decoder::Stream::State state___ = decoder->get_FLAC_stream_decoder_state();

View File

@ -79,10 +79,10 @@ static FLAC__bool die_ss_(const char *msg, const OggFLAC__SeekableStreamDecoder
printf("FAILED");
printf(", state = %u (%s)\n", (unsigned)state, OggFLAC__SeekableStreamDecoderStateString[state]);
if(state == OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR) {
FLAC__SeekableStreamDecoderState state_ = OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state(decoder);
printf(" FLAC seekable stream decoder state = %u (%s)\n", (unsigned)state_, FLAC__SeekableStreamDecoderStateString[state_]);
if(state_ == FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
if(state == OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
OggFLAC__StreamDecoderState state_ = OggFLAC__seekable_stream_decoder_get_stream_decoder_state(decoder);
printf(" stream decoder state = %u (%s)\n", (unsigned)state_, OggFLAC__StreamDecoderStateString[state_]);
if(state_ == OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR) {
FLAC__StreamDecoderState state__ = OggFLAC__seekable_stream_decoder_get_FLAC_stream_decoder_state(decoder);
printf(" FLAC stream decoder state = %u (%s)\n", (unsigned)state__, FLAC__StreamDecoderStateString[state__]);
}
@ -104,10 +104,10 @@ static FLAC__bool die_f_(const char *msg, const OggFLAC__FileDecoder *decoder)
if(state == OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR) {
OggFLAC__SeekableStreamDecoderState state_ = OggFLAC__file_decoder_get_seekable_stream_decoder_state(decoder);
printf(" seekable stream decoder state = %u (%s)\n", (unsigned)state_, OggFLAC__SeekableStreamDecoderStateString[state_]);
if(state_ == OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR) {
FLAC__SeekableStreamDecoderState state__ = OggFLAC__file_decoder_get_FLAC_seekable_stream_decoder_state(decoder);
printf(" FLAC seekable stream decoder state = %u (%s)\n", (unsigned)state__, FLAC__SeekableStreamDecoderStateString[state__]);
if(state__ == FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
if(state_ == OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
OggFLAC__StreamDecoderState state__ = OggFLAC__file_decoder_get_stream_decoder_state(decoder);
printf(" stream decoder state = %u (%s)\n", (unsigned)state__, OggFLAC__StreamDecoderStateString[state__]);
if(state__ == OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR) {
FLAC__StreamDecoderState state___ = OggFLAC__file_decoder_get_FLAC_stream_decoder_state(decoder);
printf(" FLAC stream decoder state = %u (%s)\n", (unsigned)state___, FLAC__StreamDecoderStateString[state___]);
}
@ -801,22 +801,22 @@ static FLAC__bool test_stream_decoder()
return true;
}
static FLAC__SeekableStreamDecoderReadStatus seekable_stream_decoder_read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
static OggFLAC__SeekableStreamDecoderReadStatus seekable_stream_decoder_read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
{
(void)decoder;
switch(stream_decoder_read_callback_(0, buffer, bytes, client_data)) {
case FLAC__STREAM_DECODER_READ_STATUS_CONTINUE:
case FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM:
return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
case FLAC__STREAM_DECODER_READ_STATUS_ABORT:
return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
default:
FLAC__ASSERT(0);
return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
}
}
static FLAC__SeekableStreamDecoderSeekStatus seekable_stream_decoder_seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
static OggFLAC__SeekableStreamDecoderSeekStatus seekable_stream_decoder_seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
{
seekable_stream_decoder_client_data_struct *dcd = (seekable_stream_decoder_client_data_struct*)client_data;
@ -824,21 +824,21 @@ static FLAC__SeekableStreamDecoderSeekStatus seekable_stream_decoder_seek_callba
if(0 == dcd) {
printf("ERROR: client_data in seek callback is NULL\n");
return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
}
if(dcd->error_occurred)
return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
if(fseek(dcd->file, (long)absolute_byte_offset, SEEK_SET) < 0) {
dcd->error_occurred = true;
return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
}
return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
}
static FLAC__SeekableStreamDecoderTellStatus seekable_stream_decoder_tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
static OggFLAC__SeekableStreamDecoderTellStatus seekable_stream_decoder_tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
{
seekable_stream_decoder_client_data_struct *dcd = (seekable_stream_decoder_client_data_struct*)client_data;
long offset;
@ -847,24 +847,24 @@ static FLAC__SeekableStreamDecoderTellStatus seekable_stream_decoder_tell_callba
if(0 == dcd) {
printf("ERROR: client_data in tell callback is NULL\n");
return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
}
if(dcd->error_occurred)
return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
offset = ftell(dcd->file);
*absolute_byte_offset = (FLAC__uint64)offset;
if(offset < 0) {
dcd->error_occurred = true;
return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
}
return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
}
static FLAC__SeekableStreamDecoderLengthStatus seekable_stream_decoder_length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
static OggFLAC__SeekableStreamDecoderLengthStatus seekable_stream_decoder_length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
{
seekable_stream_decoder_client_data_struct *dcd = (seekable_stream_decoder_client_data_struct*)client_data;
@ -872,14 +872,14 @@ static FLAC__SeekableStreamDecoderLengthStatus seekable_stream_decoder_length_ca
if(0 == dcd) {
printf("ERROR: client_data in length callback is NULL\n");
return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
}
if(dcd->error_occurred)
return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
*stream_length = (FLAC__uint64)oggflacfilesize_;
return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
}
static FLAC__bool seekable_stream_decoder_eof_callback_(const OggFLAC__SeekableStreamDecoder *decoder, void *client_data)
@ -977,7 +977,7 @@ static FLAC__bool test_seekable_stream_decoder()
{
OggFLAC__SeekableStreamDecoder *decoder;
OggFLAC__SeekableStreamDecoderState state;
FLAC__SeekableStreamDecoderState fsstate;
OggFLAC__StreamDecoderState sstate;
FLAC__StreamDecoderState fstate;
seekable_stream_decoder_client_data_struct decoder_client_data;
@ -1087,9 +1087,9 @@ static FLAC__bool test_seekable_stream_decoder()
state = OggFLAC__seekable_stream_decoder_get_state(decoder);
printf("returned state = %u (%s)... OK\n", state, OggFLAC__SeekableStreamDecoderStateString[state]);
printf("testing OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state()... ");
fsstate = OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state(decoder);
printf("returned state = %u (%s)... OK\n", fsstate, FLAC__SeekableStreamDecoderStateString[fsstate]);
printf("testing OggFLAC__seekable_stream_decoder_get_stream_decoder_state()... ");
sstate = OggFLAC__seekable_stream_decoder_get_stream_decoder_state(decoder);
printf("returned state = %u (%s)... OK\n", sstate, OggFLAC__StreamDecoderStateString[sstate]);
printf("testing OggFLAC__seekable_stream_decoder_get_FLAC_stream_decoder_state()... ");
fstate = OggFLAC__seekable_stream_decoder_get_FLAC_stream_decoder_state(decoder);
@ -1581,8 +1581,8 @@ static FLAC__bool test_file_decoder()
{
OggFLAC__FileDecoder *decoder;
OggFLAC__FileDecoderState state;
OggFLAC__SeekableStreamDecoderState sstate;
FLAC__SeekableStreamDecoderState fsstate;
OggFLAC__SeekableStreamDecoderState ssstate;
OggFLAC__StreamDecoderState sstate;
FLAC__StreamDecoderState fstate;
seekable_stream_decoder_client_data_struct decoder_client_data;
@ -1673,12 +1673,12 @@ static FLAC__bool test_file_decoder()
printf("returned state = %u (%s)... OK\n", state, OggFLAC__FileDecoderStateString[state]);
printf("testing OggFLAC__file_decoder_get_seekable_stream_decoder_state()... ");
sstate = OggFLAC__file_decoder_get_seekable_stream_decoder_state(decoder);
printf("returned state = %u (%s)... OK\n", sstate, OggFLAC__SeekableStreamDecoderStateString[sstate]);
ssstate = OggFLAC__file_decoder_get_seekable_stream_decoder_state(decoder);
printf("returned state = %u (%s)... OK\n", ssstate, OggFLAC__SeekableStreamDecoderStateString[ssstate]);
printf("testing OggFLAC__file_decoder_get_FLAC_seekable_stream_decoder_state()... ");
fsstate = OggFLAC__file_decoder_get_FLAC_seekable_stream_decoder_state(decoder);
printf("returned state = %u (%s)... OK\n", fsstate, FLAC__SeekableStreamDecoderStateString[fsstate]);
printf("testing OggFLAC__file_decoder_get_stream_decoder_state()... ");
sstate = OggFLAC__file_decoder_get_stream_decoder_state(decoder);
printf("returned state = %u (%s)... OK\n", sstate, OggFLAC__StreamDecoderStateString[sstate]);
printf("testing OggFLAC__file_decoder_get_FLAC_stream_decoder_state()... ");
fstate = OggFLAC__file_decoder_get_FLAC_stream_decoder_state(decoder);