mirror of
https://github.com/claunia/flac.git
synced 2025-12-16 18:54:26 +00:00
many fixes
This commit is contained in:
@@ -18,9 +18,16 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h> /* for memset() */
|
||||
#include "ogg/ogg.h"
|
||||
#include "FLAC/assert.h"
|
||||
#include "protected/stream_decoder.h"
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
#define min(x,y) ((x)<(y)?(x):(y))
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Private class method prototypes
|
||||
@@ -28,10 +35,10 @@
|
||||
***********************************************************************/
|
||||
|
||||
static void set_defaults_(OggFLAC__StreamDecoder *decoder);
|
||||
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__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
|
||||
static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
|
||||
static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
|
||||
static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
@@ -62,6 +69,7 @@ typedef struct OggFLAC__StreamDecoderPrivate {
|
||||
const char * const OggFLAC__StreamDecoderStateString[] = {
|
||||
"OggFLAC__STREAM_DECODER_OK",
|
||||
"OggFLAC__STREAM_DECODER_OGG_ERROR",
|
||||
"OggFLAC__STREAM_DECODER_READ_ERROR",
|
||||
"OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR",
|
||||
"OggFLAC__STREAM_DECODER_INVALID_CALLBACK",
|
||||
"OggFLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
|
||||
@@ -75,80 +83,57 @@ const char * const OggFLAC__StreamDecoderStateString[] = {
|
||||
* Class constructor/destructor
|
||||
*
|
||||
***********************************************************************/
|
||||
FLAC__StreamDecoder *FLAC__stream_decoder_new()
|
||||
OggFLAC__StreamDecoder *OggFLAC__stream_decoder_new()
|
||||
{
|
||||
FLAC__StreamDecoder *decoder;
|
||||
unsigned i;
|
||||
OggFLAC__StreamDecoder *decoder;
|
||||
|
||||
FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
|
||||
|
||||
decoder = (FLAC__StreamDecoder*)malloc(sizeof(FLAC__StreamDecoder));
|
||||
decoder = (OggFLAC__StreamDecoder*)malloc(sizeof(OggFLAC__StreamDecoder));
|
||||
if(decoder == 0) {
|
||||
return 0;
|
||||
}
|
||||
memset(decoder, 0, sizeof(FLAC__StreamDecoder));
|
||||
memset(decoder, 0, sizeof(OggFLAC__StreamDecoder));
|
||||
|
||||
decoder->protected_ = (FLAC__StreamDecoderProtected*)malloc(sizeof(FLAC__StreamDecoderProtected));
|
||||
decoder->protected_ = (OggFLAC__StreamDecoderProtected*)malloc(sizeof(OggFLAC__StreamDecoderProtected));
|
||||
if(decoder->protected_ == 0) {
|
||||
free(decoder);
|
||||
return 0;
|
||||
}
|
||||
memset(decoder->protected_, 0, sizeof(FLAC__StreamDecoderProtected));
|
||||
memset(decoder->protected_, 0, sizeof(OggFLAC__StreamDecoderProtected));
|
||||
|
||||
decoder->private_ = (FLAC__StreamDecoderPrivate*)malloc(sizeof(FLAC__StreamDecoderPrivate));
|
||||
decoder->private_ = (OggFLAC__StreamDecoderPrivate*)malloc(sizeof(OggFLAC__StreamDecoderPrivate));
|
||||
if(decoder->private_ == 0) {
|
||||
free(decoder->protected_);
|
||||
free(decoder);
|
||||
return 0;
|
||||
}
|
||||
memset(decoder->private_, 0, sizeof(FLAC__StreamDecoderPrivate));
|
||||
memset(decoder->private_, 0, sizeof(OggFLAC__StreamDecoderPrivate));
|
||||
|
||||
decoder->private_->input = FLAC__bitbuffer_new();
|
||||
if(decoder->private_->input == 0) {
|
||||
decoder->private_->FLAC_stream_decoder = FLAC__stream_decoder_new();
|
||||
if(0 == decoder->private_->FLAC_stream_decoder) {
|
||||
free(decoder->private_);
|
||||
free(decoder->protected_);
|
||||
free(decoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
decoder->private_->metadata_filter_ids_capacity = 16;
|
||||
if(0 == (decoder->private_->metadata_filter_ids = malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) {
|
||||
FLAC__bitbuffer_delete(decoder->private_->input);
|
||||
free(decoder->private_);
|
||||
free(decoder->protected_);
|
||||
free(decoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
|
||||
decoder->private_->output[i] = 0;
|
||||
decoder->private_->residual[i] = 0;
|
||||
}
|
||||
|
||||
decoder->private_->output_capacity = 0;
|
||||
decoder->private_->output_channels = 0;
|
||||
decoder->private_->has_seek_table = false;
|
||||
|
||||
set_defaults_(decoder);
|
||||
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED;
|
||||
decoder->protected_->state = OggFLAC__STREAM_DECODER_UNINITIALIZED;
|
||||
|
||||
return decoder;
|
||||
}
|
||||
|
||||
void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder)
|
||||
void OggFLAC__stream_decoder_delete(OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->private_->input);
|
||||
FLAC__ASSERT(0 != decoder->private_->FLAC_stream_decoder);
|
||||
|
||||
FLAC__stream_decoder_finish(decoder);
|
||||
OggFLAC__stream_decoder_finish(decoder);
|
||||
|
||||
if(0 != decoder->private_->metadata_filter_ids)
|
||||
free(decoder->private_->metadata_filter_ids);
|
||||
FLAC__stream_decoder_delete(decoder->private_->FLAC_stream_decoder);
|
||||
|
||||
FLAC__bitbuffer_delete(decoder->private_->input);
|
||||
free(decoder->private_);
|
||||
free(decoder->protected_);
|
||||
free(decoder);
|
||||
@@ -160,464 +145,361 @@ void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder)
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
FLAC__StreamDecoderState FLAC__stream_decoder_init(FLAC__StreamDecoder *decoder)
|
||||
OggFLAC__StreamDecoderState OggFLAC__stream_decoder_init(OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
|
||||
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return decoder->protected_->state = FLAC__STREAM_DECODER_ALREADY_INITIALIZED;
|
||||
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return decoder->protected_->state = OggFLAC__STREAM_DECODER_ALREADY_INITIALIZED;
|
||||
|
||||
if(0 == decoder->private_->read_callback || 0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
|
||||
return decoder->protected_->state = FLAC__STREAM_DECODER_INVALID_CALLBACK;
|
||||
return decoder->protected_->state = OggFLAC__STREAM_DECODER_INVALID_CALLBACK;
|
||||
|
||||
if(!FLAC__bitbuffer_init(decoder->private_->input))
|
||||
return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
if(ogg_stream_init(&decoder->private_->ogg.stream_state, 0) != 0)
|
||||
return decoder->protected_->state = OggFLAC__STREAM_DECODER_OGG_ERROR;
|
||||
|
||||
decoder->private_->last_frame_number = 0;
|
||||
decoder->private_->samples_decoded = 0;
|
||||
decoder->private_->has_stream_info = false;
|
||||
decoder->private_->cached = false;
|
||||
if(ogg_sync_init(&decoder->private_->ogg.sync_state) != 0)
|
||||
return decoder->protected_->state = OggFLAC__STREAM_DECODER_OGG_ERROR;
|
||||
|
||||
/*
|
||||
* get the CPU info and set the function pointers
|
||||
*/
|
||||
FLAC__cpu_info(&decoder->private_->cpuinfo);
|
||||
/* first default to the non-asm routines */
|
||||
decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal;
|
||||
decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal;
|
||||
/* now override with asm where appropriate */
|
||||
#ifndef FLAC__NO_ASM
|
||||
if(decoder->private_->cpuinfo.use_asm) {
|
||||
#ifdef FLAC__CPU_IA32
|
||||
FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
|
||||
#ifdef FLAC__HAS_NASM
|
||||
if(decoder->private_->cpuinfo.data.ia32.mmx) {
|
||||
decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
|
||||
decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx;
|
||||
}
|
||||
else {
|
||||
decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
|
||||
decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
FLAC__stream_decoder_set_read_callback(decoder->private_->FLAC_stream_decoder, read_callback_);
|
||||
FLAC__stream_decoder_set_write_callback(decoder->private_->FLAC_stream_decoder, write_callback_);
|
||||
FLAC__stream_decoder_set_metadata_callback(decoder->private_->FLAC_stream_decoder, metadata_callback_);
|
||||
FLAC__stream_decoder_set_error_callback(decoder->private_->FLAC_stream_decoder, error_callback_);
|
||||
FLAC__stream_decoder_set_client_data(decoder->private_->FLAC_stream_decoder, decoder);
|
||||
|
||||
if(!FLAC__stream_decoder_reset(decoder))
|
||||
return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
if(FLAC__stream_decoder_init(decoder->private_->FLAC_stream_decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
|
||||
return decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
|
||||
|
||||
return decoder->protected_->state;
|
||||
return decoder->protected_->state = OggFLAC__STREAM_DECODER_OK;
|
||||
}
|
||||
|
||||
void FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder)
|
||||
{
|
||||
unsigned i;
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
if(decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return;
|
||||
if(decoder->private_->has_seek_table) {
|
||||
FLAC__ASSERT(0 != decoder->private_->seek_table.data.seek_table.points);
|
||||
free(decoder->private_->seek_table.data.seek_table.points);
|
||||
decoder->private_->seek_table.data.seek_table.points = 0;
|
||||
decoder->private_->has_seek_table = false;
|
||||
}
|
||||
FLAC__bitbuffer_free(decoder->private_->input);
|
||||
for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
|
||||
/* WATCHOUT: FLAC__lpc_restore_signal_asm_ia32_mmx() requires that the output arrays have a buffer of up to 3 zeroes in front (at negative indices) for alignment purposes; we use 4 to keep the data well-aligned. */
|
||||
if(0 != decoder->private_->output[i]) {
|
||||
free(decoder->private_->output[i]-4);
|
||||
decoder->private_->output[i] = 0;
|
||||
}
|
||||
if(0 != decoder->private_->residual[i]) {
|
||||
free(decoder->private_->residual[i]);
|
||||
decoder->private_->residual[i] = 0;
|
||||
}
|
||||
}
|
||||
decoder->private_->output_capacity = 0;
|
||||
decoder->private_->output_channels = 0;
|
||||
|
||||
set_defaults_(decoder);
|
||||
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_set_read_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderReadCallback value)
|
||||
void OggFLAC__stream_decoder_finish(OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
|
||||
if(decoder->protected_->state == OggFLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return;
|
||||
|
||||
FLAC__ASSERT(0 != decoder->private_->FLAC_stream_decoder);
|
||||
|
||||
FLAC__stream_decoder_finish(decoder->private_->FLAC_stream_decoder);
|
||||
|
||||
(void)ogg_sync_clear(&decoder->private_->ogg.sync_state);
|
||||
(void)ogg_stream_clear(&decoder->private_->ogg.stream_state);
|
||||
|
||||
set_defaults_(decoder);
|
||||
|
||||
decoder->protected_->state = OggFLAC__STREAM_DECODER_UNINITIALIZED;
|
||||
}
|
||||
|
||||
FLAC__bool OggFLAC__stream_decoder_set_read_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderReadCallback value)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return false;
|
||||
decoder->private_->read_callback = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_set_write_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderWriteCallback value)
|
||||
FLAC__bool OggFLAC__stream_decoder_set_write_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderWriteCallback value)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return false;
|
||||
decoder->private_->write_callback = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_set_metadata_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderMetadataCallback value)
|
||||
FLAC__bool OggFLAC__stream_decoder_set_metadata_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderMetadataCallback value)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return false;
|
||||
decoder->private_->metadata_callback = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_set_error_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorCallback value)
|
||||
FLAC__bool OggFLAC__stream_decoder_set_error_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderErrorCallback value)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return false;
|
||||
decoder->private_->error_callback = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_set_client_data(FLAC__StreamDecoder *decoder, void *value)
|
||||
FLAC__bool OggFLAC__stream_decoder_set_client_data(OggFLAC__StreamDecoder *decoder, void *value)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return false;
|
||||
decoder->private_->client_data = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type)
|
||||
FLAC__bool OggFLAC__stream_decoder_set_metadata_respond(OggFLAC__StreamDecoder *decoder, FLAC__MetadataType type)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
FLAC__ASSERT(type <= FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
||||
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return false;
|
||||
decoder->private_->metadata_filter[type] = true;
|
||||
if(type == FLAC__METADATA_TYPE_APPLICATION)
|
||||
decoder->private_->metadata_filter_ids_count = 0;
|
||||
return true;
|
||||
return FLAC__stream_decoder_set_metadata_respond(decoder->private_->FLAC_stream_decoder, type);
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4])
|
||||
FLAC__bool OggFLAC__stream_decoder_set_metadata_respond_application(OggFLAC__StreamDecoder *decoder, const FLAC__byte id[4])
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
FLAC__ASSERT(0 != id);
|
||||
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return false;
|
||||
|
||||
if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION])
|
||||
return true;
|
||||
|
||||
FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
|
||||
|
||||
if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
|
||||
if(0 == (decoder->private_->metadata_filter_ids = realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2)))
|
||||
return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
decoder->private_->metadata_filter_ids_capacity *= 2;
|
||||
}
|
||||
|
||||
memcpy(decoder->private_->metadata_filter_ids + decoder->private_->metadata_filter_ids_count * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8));
|
||||
decoder->private_->metadata_filter_ids_count++;
|
||||
|
||||
return true;
|
||||
return FLAC__stream_decoder_set_metadata_respond_application(decoder->private_->FLAC_stream_decoder, id);
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder)
|
||||
{
|
||||
unsigned i;
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return false;
|
||||
for(i = 0; i < sizeof(decoder->private_->metadata_filter) / sizeof(decoder->private_->metadata_filter[0]); i++)
|
||||
decoder->private_->metadata_filter[i] = true;
|
||||
decoder->private_->metadata_filter_ids_count = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type)
|
||||
FLAC__bool OggFLAC__stream_decoder_set_metadata_respond_all(OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
FLAC__ASSERT(type <= FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
||||
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return false;
|
||||
decoder->private_->metadata_filter[type] = false;
|
||||
if(type == FLAC__METADATA_TYPE_APPLICATION)
|
||||
decoder->private_->metadata_filter_ids_count = 0;
|
||||
return true;
|
||||
return FLAC__stream_decoder_set_metadata_respond_all(decoder->private_->FLAC_stream_decoder);
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4])
|
||||
FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore(OggFLAC__StreamDecoder *decoder, FLAC__MetadataType type)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
FLAC__ASSERT(0 != id);
|
||||
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return false;
|
||||
|
||||
if(!decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION])
|
||||
return true;
|
||||
|
||||
FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
|
||||
|
||||
if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
|
||||
if(0 == (decoder->private_->metadata_filter_ids = realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2)))
|
||||
return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
decoder->private_->metadata_filter_ids_capacity *= 2;
|
||||
}
|
||||
|
||||
memcpy(decoder->private_->metadata_filter_ids + decoder->private_->metadata_filter_ids_count * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8));
|
||||
decoder->private_->metadata_filter_ids_count++;
|
||||
|
||||
return true;
|
||||
return FLAC__stream_decoder_set_metadata_ignore(decoder->private_->FLAC_stream_decoder, type);
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder)
|
||||
FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore_application(OggFLAC__StreamDecoder *decoder, const FLAC__byte id[4])
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return false;
|
||||
memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter));
|
||||
decoder->private_->metadata_filter_ids_count = 0;
|
||||
return true;
|
||||
return FLAC__stream_decoder_set_metadata_ignore_application(decoder->private_->FLAC_stream_decoder, id);
|
||||
}
|
||||
|
||||
FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder)
|
||||
FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore_all(OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_decoder_set_metadata_ignore_all(decoder->private_->FLAC_stream_decoder);
|
||||
}
|
||||
|
||||
OggFLAC__StreamDecoderState OggFLAC__stream_decoder_get_state(const OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
return decoder->protected_->state;
|
||||
}
|
||||
|
||||
unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder)
|
||||
FLAC__StreamDecoderState OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(const OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
return decoder->protected_->channels;
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
return FLAC__stream_decoder_get_state(decoder->private_->FLAC_stream_decoder);
|
||||
}
|
||||
|
||||
FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder)
|
||||
unsigned OggFLAC__stream_decoder_get_channels(const OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
return decoder->protected_->channel_assignment;
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
return FLAC__stream_decoder_get_channels(decoder->private_->FLAC_stream_decoder);
|
||||
}
|
||||
|
||||
unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder)
|
||||
FLAC__ChannelAssignment OggFLAC__stream_decoder_get_channel_assignment(const OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
return decoder->protected_->bits_per_sample;
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
return FLAC__stream_decoder_get_channel_assignment(decoder->private_->FLAC_stream_decoder);
|
||||
}
|
||||
|
||||
unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder)
|
||||
unsigned OggFLAC__stream_decoder_get_bits_per_sample(const OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
return decoder->protected_->sample_rate;
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
return FLAC__stream_decoder_get_bits_per_sample(decoder->private_->FLAC_stream_decoder);
|
||||
}
|
||||
|
||||
unsigned FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder)
|
||||
unsigned OggFLAC__stream_decoder_get_sample_rate(const OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
return decoder->protected_->blocksize;
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
return FLAC__stream_decoder_get_sample_rate(decoder->private_->FLAC_stream_decoder);
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder)
|
||||
unsigned OggFLAC__stream_decoder_get_blocksize(const OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
return FLAC__stream_decoder_get_blocksize(decoder->private_->FLAC_stream_decoder);
|
||||
}
|
||||
|
||||
FLAC__bool OggFLAC__stream_decoder_flush(OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
|
||||
if(!FLAC__bitbuffer_clear(decoder->private_->input)) {
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
(void)ogg_sync_clear(&decoder->private_->ogg.sync_state);
|
||||
|
||||
if(!FLAC__stream_decoder_flush(decoder->private_->FLAC_stream_decoder)) {
|
||||
decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
|
||||
return false;
|
||||
}
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
||||
|
||||
decoder->protected_->state = OggFLAC__STREAM_DECODER_OK;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder)
|
||||
FLAC__bool OggFLAC__stream_decoder_reset(OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
|
||||
if(!FLAC__stream_decoder_flush(decoder)) {
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
if(!OggFLAC__stream_decoder_flush(decoder)) {
|
||||
decoder->protected_->state = OggFLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
}
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA;
|
||||
|
||||
decoder->private_->samples_decoded = 0;
|
||||
if(!FLAC__stream_decoder_reset(decoder->private_->FLAC_stream_decoder)) {
|
||||
decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
decoder->protected_->state = OggFLAC__STREAM_DECODER_OK;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__bool got_a_frame;
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
|
||||
while(1) {
|
||||
switch(decoder->protected_->state) {
|
||||
case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
|
||||
if(!find_metadata_(decoder))
|
||||
return false; /* above function sets the status for us */
|
||||
break;
|
||||
case FLAC__STREAM_DECODER_READ_METADATA:
|
||||
if(!read_metadata_(decoder))
|
||||
return false; /* above function sets the status for us */
|
||||
else
|
||||
return true;
|
||||
case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
|
||||
if(!frame_sync_(decoder))
|
||||
return true; /* above function sets the status for us */
|
||||
break;
|
||||
case FLAC__STREAM_DECODER_READ_FRAME:
|
||||
if(!read_frame_(decoder, &got_a_frame))
|
||||
return false; /* above function sets the status for us */
|
||||
if(got_a_frame)
|
||||
return true; /* above function sets the status for us */
|
||||
break;
|
||||
case FLAC__STREAM_DECODER_END_OF_STREAM:
|
||||
case FLAC__STREAM_DECODER_ABORTED:
|
||||
return true;
|
||||
default:
|
||||
FLAC__ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder)
|
||||
FLAC__bool OggFLAC__stream_decoder_process_single(OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
|
||||
while(1) {
|
||||
switch(decoder->protected_->state) {
|
||||
case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
|
||||
if(!find_metadata_(decoder))
|
||||
return false; /* above function sets the status for us */
|
||||
break;
|
||||
case FLAC__STREAM_DECODER_READ_METADATA:
|
||||
if(!read_metadata_(decoder))
|
||||
return false; /* above function sets the status for us */
|
||||
break;
|
||||
case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
|
||||
case FLAC__STREAM_DECODER_READ_FRAME:
|
||||
case FLAC__STREAM_DECODER_END_OF_STREAM:
|
||||
case FLAC__STREAM_DECODER_ABORTED:
|
||||
return true;
|
||||
default:
|
||||
FLAC__ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
return FLAC__stream_decoder_process_single(decoder->private_->FLAC_stream_decoder);
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__bool dummy;
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->protected_);
|
||||
|
||||
while(1) {
|
||||
switch(decoder->protected_->state) {
|
||||
case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
|
||||
if(!find_metadata_(decoder))
|
||||
return false; /* above function sets the status for us */
|
||||
break;
|
||||
case FLAC__STREAM_DECODER_READ_METADATA:
|
||||
if(!read_metadata_(decoder))
|
||||
return false; /* above function sets the status for us */
|
||||
break;
|
||||
case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
|
||||
if(!frame_sync_(decoder))
|
||||
return true; /* above function sets the status for us */
|
||||
break;
|
||||
case FLAC__STREAM_DECODER_READ_FRAME:
|
||||
if(!read_frame_(decoder, &dummy))
|
||||
return false; /* above function sets the status for us */
|
||||
break;
|
||||
case FLAC__STREAM_DECODER_END_OF_STREAM:
|
||||
case FLAC__STREAM_DECODER_ABORTED:
|
||||
return true;
|
||||
default:
|
||||
FLAC__ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Protected class methods
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder)
|
||||
FLAC__bool OggFLAC__stream_decoder_process_until_end_of_metadata(OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
return FLAC__bitbuffer_get_input_bytes_unconsumed(decoder->private_->input);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
return FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->FLAC_stream_decoder);
|
||||
}
|
||||
|
||||
FLAC__bool OggFLAC__stream_decoder_process_until_end_of_stream(OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
return FLAC__stream_decoder_process_until_end_of_stream(decoder->private_->FLAC_stream_decoder);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Private class methods
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
void set_defaults_(FLAC__StreamDecoder *decoder)
|
||||
void set_defaults_(OggFLAC__StreamDecoder *decoder)
|
||||
{
|
||||
decoder->private_->read_callback = 0;
|
||||
decoder->private_->write_callback = 0;
|
||||
decoder->private_->metadata_callback = 0;
|
||||
decoder->private_->error_callback = 0;
|
||||
decoder->private_->client_data = 0;
|
||||
|
||||
memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter));
|
||||
decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] = true;
|
||||
decoder->private_->metadata_filter_ids_count = 0;
|
||||
}
|
||||
|
||||
FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
|
||||
FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *unused, FLAC__byte buffer[], unsigned *bytes, void *client_data)
|
||||
{
|
||||
static const unsigned OGG_BYTES_CHUNK = 8192;
|
||||
OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
|
||||
unsigned ogg_bytes_to_read, ogg_bytes_read;
|
||||
ogg_page page;
|
||||
char *oggbuf;
|
||||
|
||||
(void)unused;
|
||||
|
||||
/*
|
||||
* We have to be careful not to read in more than the
|
||||
* FLAC__StreamDecoder says it has room for. We know
|
||||
* that the size of the decoded data must be no more
|
||||
* than the encoded data we will read.
|
||||
*/
|
||||
ogg_bytes_to_read = min(*bytes, OGG_BYTES_CHUNK);
|
||||
oggbuf = ogg_sync_buffer(&decoder->private_->ogg.sync_state, ogg_bytes_to_read);
|
||||
|
||||
if(decoder->private_->read_callback(decoder, oggbuf, &ogg_bytes_to_read, decoder->private_->client_data) != FLAC__STREAM_DECODER_READ_STATUS_CONTINUE) {
|
||||
decoder->protected_->state = OggFLAC__STREAM_DECODER_READ_ERROR;
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
|
||||
}
|
||||
ogg_bytes_read = ogg_bytes_to_read;
|
||||
|
||||
if(ogg_sync_wrote(&decoder->private_->ogg.sync_state, ogg_bytes_read) < 0) {
|
||||
decoder->protected_->state = OggFLAC__STREAM_DECODER_READ_ERROR;
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
|
||||
}
|
||||
|
||||
*bytes = 0;
|
||||
while(ogg_sync_pageout(&decoder->private_->ogg.sync_state, &page) == 1) {
|
||||
if(ogg_stream_pagein(&decoder->private_->ogg.stream_state, &page) == 0) {
|
||||
ogg_packet packet;
|
||||
|
||||
while(ogg_stream_packetout(&decoder->private_->ogg.stream_state, &packet) == 1) {
|
||||
memcpy(buffer, packet.packet, packet.bytes);
|
||||
*bytes += packet.bytes;
|
||||
buffer += packet.bytes;
|
||||
}
|
||||
} else {
|
||||
decoder->protected_->state = OggFLAC__STREAM_DECODER_READ_ERROR;
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
|
||||
}
|
||||
}
|
||||
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
|
||||
FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *unused, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
|
||||
{
|
||||
OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
|
||||
(void)unused;
|
||||
return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
|
||||
}
|
||||
|
||||
void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
|
||||
void metadata_callback_(const FLAC__StreamDecoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
|
||||
{
|
||||
OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
|
||||
(void)unused;
|
||||
return decoder->private_->metadata_callback(decoder, metadata, decoder->private_->client_data);
|
||||
}
|
||||
|
||||
void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
|
||||
void error_callback_(const FLAC__StreamDecoder *unused, FLAC__StreamDecoderErrorStatus status, void *client_data)
|
||||
{
|
||||
OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
|
||||
(void)unused;
|
||||
return decoder->private_->error_callback(decoder, status, decoder->private_->client_data);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
static void set_defaults_(FLAC__StreamEncoder *encoder);
|
||||
static void set_defaults_(OggFLAC__StreamEncoder *encoder);
|
||||
static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
|
||||
static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
|
||||
|
||||
@@ -42,7 +42,7 @@ static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__S
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
typedef struct FLAC__StreamEncoderPrivate {
|
||||
typedef struct OggFLAC__StreamEncoderPrivate {
|
||||
OggFLAC__StreamEncoderWriteCallback write_callback;
|
||||
void *client_data;
|
||||
FLAC__StreamEncoder *FLAC_stream_encoder;
|
||||
@@ -53,7 +53,7 @@ typedef struct FLAC__StreamEncoderPrivate {
|
||||
ogg_stream_state stream_state;
|
||||
ogg_page page;
|
||||
} ogg;
|
||||
} FLAC__StreamEncoderPrivate;
|
||||
} OggFLAC__StreamEncoderPrivate;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
@@ -141,7 +141,7 @@ void OggFLAC__stream_encoder_delete(OggFLAC__StreamEncoder *encoder)
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
OggFLAC__StreamEncoderState OggFLAC__stream_encoder_init(FLAC__StreamEncoder *encoder)
|
||||
OggFLAC__StreamEncoderState OggFLAC__stream_encoder_init(OggFLAC__StreamEncoder *encoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != encoder);
|
||||
|
||||
@@ -151,7 +151,7 @@ OggFLAC__StreamEncoderState OggFLAC__stream_encoder_init(FLAC__StreamEncoder *en
|
||||
if(0 == encoder->private_->write_callback)
|
||||
return encoder->protected_->state = OggFLAC__STREAM_ENCODER_INVALID_CALLBACK;
|
||||
|
||||
if(ogg_stream_init(&encoder->private_->ogg.stream_state, 0) != 0)
|
||||
if(ogg_stream_init(&encoder->private_->ogg.stream_state, /*@@@serialno=*/0) != 0)
|
||||
return encoder->protected_->state = OggFLAC__STREAM_ENCODER_OGG_ERROR;
|
||||
|
||||
FLAC__stream_encoder_set_write_callback(encoder->private_->FLAC_stream_encoder, write_callback_);
|
||||
@@ -180,20 +180,20 @@ void OggFLAC__stream_encoder_finish(OggFLAC__StreamEncoder *encoder)
|
||||
|
||||
FLAC__stream_encoder_finish(encoder->private_->FLAC_stream_encoder);
|
||||
|
||||
ogg_stream_clear(&encoder->private_->ogg.stream_state);
|
||||
(void)ogg_stream_clear(&encoder->private_->ogg.stream_state);
|
||||
|
||||
set_defaults_(encoder);
|
||||
|
||||
encoder->protected_->state = OggFLAC__STREAM_ENCODER_UNINITIALIZED;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value)
|
||||
FLAC__bool OggFLAC__stream_encoder_set_verify(OggFLAC__StreamEncoder *encoder, FLAC__bool value)
|
||||
{
|
||||
FLAC__ASSERT(0 != encoder);
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_verify(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -204,7 +204,7 @@ FLAC__bool OggFLAC__stream_encoder_set_streamable_subset(OggFLAC__StreamEncoder
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_streamable_subset(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -215,7 +215,7 @@ FLAC__bool OggFLAC__stream_encoder_set_do_mid_side_stereo(OggFLAC__StreamEncoder
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -226,7 +226,7 @@ FLAC__bool OggFLAC__stream_encoder_set_loose_mid_side_stereo(OggFLAC__StreamEnco
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -237,7 +237,7 @@ FLAC__bool OggFLAC__stream_encoder_set_channels(OggFLAC__StreamEncoder *encoder,
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_channels(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -248,7 +248,7 @@ FLAC__bool OggFLAC__stream_encoder_set_bits_per_sample(OggFLAC__StreamEncoder *e
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -259,7 +259,7 @@ FLAC__bool OggFLAC__stream_encoder_set_sample_rate(OggFLAC__StreamEncoder *encod
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_sample_rate(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -270,7 +270,7 @@ FLAC__bool OggFLAC__stream_encoder_set_blocksize(OggFLAC__StreamEncoder *encoder
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_blocksize(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -281,7 +281,7 @@ FLAC__bool OggFLAC__stream_encoder_set_max_lpc_order(OggFLAC__StreamEncoder *enc
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -292,7 +292,7 @@ FLAC__bool OggFLAC__stream_encoder_set_qlp_coeff_precision(OggFLAC__StreamEncode
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -303,7 +303,7 @@ FLAC__bool OggFLAC__stream_encoder_set_do_qlp_coeff_prec_search(OggFLAC__StreamE
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -314,7 +314,7 @@ FLAC__bool OggFLAC__stream_encoder_set_do_escape_coding(OggFLAC__StreamEncoder *
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -325,7 +325,7 @@ FLAC__bool OggFLAC__stream_encoder_set_do_exhaustive_model_search(OggFLAC__Strea
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -336,7 +336,7 @@ FLAC__bool OggFLAC__stream_encoder_set_min_residual_partition_order(OggFLAC__Str
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -347,7 +347,7 @@ FLAC__bool OggFLAC__stream_encoder_set_max_residual_partition_order(OggFLAC__Str
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -358,7 +358,7 @@ FLAC__bool OggFLAC__stream_encoder_set_rice_parameter_search_dist(OggFLAC__Strea
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -369,7 +369,7 @@ FLAC__bool OggFLAC__stream_encoder_set_total_samples_estimate(OggFLAC__StreamEnc
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->FLAC_stream_encoder, value);
|
||||
}
|
||||
@@ -380,9 +380,9 @@ FLAC__bool OggFLAC__stream_encoder_set_metadata(OggFLAC__StreamEncoder *encoder,
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
FLAC__ASSERT(0 != encoder->protected_);
|
||||
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||
return false;
|
||||
return FLAC__stream_encoder_set_metadata(encoder->private_->FLAC_stream_encoder, value);
|
||||
return FLAC__stream_encoder_set_metadata(encoder->private_->FLAC_stream_encoder, metadata, num_blocks);
|
||||
}
|
||||
|
||||
FLAC__bool OggFLAC__stream_encoder_set_write_callback(OggFLAC__StreamEncoder *encoder, OggFLAC__StreamEncoderWriteCallback value)
|
||||
@@ -424,7 +424,7 @@ FLAC__StreamEncoderState OggFLAC__stream_encoder_get_FLAC_stream_encoder_state(c
|
||||
return FLAC__stream_encoder_get_state(encoder->private_->FLAC_stream_encoder);
|
||||
}
|
||||
|
||||
FLAC__StreamDecoderState OggFLAC__stream_encoder_get_verify_decoder_state(const OggFLAC__StreamEncoder *encoder);
|
||||
FLAC__StreamDecoderState OggFLAC__stream_encoder_get_verify_decoder_state(const OggFLAC__StreamEncoder *encoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != encoder);
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
@@ -568,7 +568,7 @@ FLAC__uint64 OggFLAC__stream_encoder_get_total_samples_estimate(const OggFLAC__S
|
||||
return FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->FLAC_stream_encoder);
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
|
||||
FLAC__bool OggFLAC__stream_encoder_process(OggFLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
|
||||
{
|
||||
FLAC__ASSERT(0 != encoder);
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
@@ -576,7 +576,7 @@ FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC
|
||||
return FLAC__stream_encoder_process(encoder->private_->FLAC_stream_encoder, buffer, samples);
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
|
||||
FLAC__bool OggFLAC__stream_encoder_process_interleaved(OggFLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
|
||||
{
|
||||
FLAC__ASSERT(0 != encoder);
|
||||
FLAC__ASSERT(0 != encoder->private_);
|
||||
@@ -590,7 +590,7 @@ FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
void set_defaults_(FLAC__StreamEncoder *encoder)
|
||||
void set_defaults_(OggFLAC__StreamEncoder *encoder)
|
||||
{
|
||||
FLAC__ASSERT(0 != encoder);
|
||||
|
||||
@@ -598,15 +598,18 @@ void set_defaults_(FLAC__StreamEncoder *encoder)
|
||||
encoder->private_->client_data = 0;
|
||||
}
|
||||
|
||||
FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
|
||||
FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *unused, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
|
||||
{
|
||||
OggFLAC__StreamEncoder *encoder = (OggFLAC__StreamEncoder*)client_data;
|
||||
ogg_packet packet;
|
||||
const FLAC__uint64 total_samples_estimate = FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->FLAC_stream_encoder);
|
||||
FLAC__ASSERT(encoder->private_->FLAC_stream_encoder == unused);
|
||||
|
||||
encoder->private_->samples_written += samples;
|
||||
|
||||
memset(&packet, 0, sizeof(packet));
|
||||
packet.packet = (unsigned char *)buffer;
|
||||
packet.granulepos = encoder->private_->samples_written - 1;
|
||||
packet.granulepos = encoder->private_->samples_written;
|
||||
/*@@@ WATCHOUT:
|
||||
* This depends on the behavior of FLAC__StreamEncoder that 'samples'
|
||||
* will be 0 for metadata writes.
|
||||
@@ -619,16 +622,17 @@ FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encode
|
||||
encoder->private_->is_first_packet = false;
|
||||
}
|
||||
|
||||
if(encoder->private_->total_samples_to_encode > 0 && encoder->private_->total_samples_to_encode == encoder->private_->samples_written)
|
||||
if(total_samples_estimate > 0 && total_samples_estimate == encoder->private_->samples_written)
|
||||
packet.e_o_s = 1;
|
||||
|
||||
ogg_stream_packetin(&encoder->private_->ogg.stream_state, &packet);
|
||||
if(ogg_stream_packetin(&encoder->private_->ogg.stream_state, &packet) != 0)
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
|
||||
while(ogg_stream_pageout(&encoder->private_->ogg.stream_state, &encoder->private_->ogg.page) != 0) {
|
||||
if(encoder->private_->write_callback(encoder, encoder->private_->ogg.page.header, encoder->private_->ogg.page.header_len) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
|
||||
if(encoder->private_->write_callback(encoder, encoder->private_->ogg.page.header, encoder->private_->ogg.page.header_len, samples, current_frame, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
|
||||
if(encoder->private_->write_callback(encoder, encoder->private_->ogg.page.body, encoder->private_->ogg.page.body_len) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
|
||||
if(encoder->private_->write_callback(encoder, encoder->private_->ogg.page.body, encoder->private_->ogg.page.body_len, samples, current_frame, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user