use new ogg decoder from libOggFLAC
authorJosh Coalson <jcoalson@users.sourceforce.net>
Wed, 7 Aug 2002 17:35:45 +0000 (17:35 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Wed, 7 Aug 2002 17:35:45 +0000 (17:35 +0000)
src/flac/decode.c

index 8b6b9db91f2b12cea1a5f1d274a6045e44faf2ae..dfb3bb94519dac2b10fbbbaeb4d0106964d3b7df 100644 (file)
 #include "decode.h"
 #include "file.h"
 #ifdef FLAC__HAS_OGG
-#include "ogg/ogg.h"
-#endif
-
-#ifdef FLAC__HAS_OGG
-typedef struct {
-       ogg_sync_state oy;
-       ogg_stream_state os;
-} ogg_info_struct;
+#include "OggFLAC/stream_decoder.h"
 #endif
 
 typedef struct {
@@ -71,11 +64,10 @@ typedef struct {
 #endif
        union {
                FLAC__FileDecoder *file;
-               FLAC__StreamDecoder *stream;
-       } decoder;
 #ifdef FLAC__HAS_OGG
-       ogg_info_struct ogg;
+               OggFLAC__StreamDecoder *stream;
 #endif
+       } decoder;
 } stream_info_struct;
 
 static FLAC__bool is_big_endian_host;
@@ -86,7 +78,7 @@ static FLAC__bool write_little_endian_uint16(FILE *f, FLAC__uint16 val);
 static FLAC__bool write_little_endian_uint32(FILE *f, FLAC__uint32 val);
 static FLAC__bool fixup_wave_chunk_size(const char *outfilename, unsigned riff_offset, unsigned data_offset, FLAC__uint32 data_size);
 #ifdef FLAC__HAS_OGG
-static FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *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);
 #endif
 /*
  * We use 'void *' so that we can use the same callbacks for the
@@ -188,14 +180,14 @@ int flac__decode_wav(const char *infilename, const char *outfilename, FLAC__bool
        else {
 #ifdef FLAC__HAS_OGG
                if(stream_info.is_ogg) {
-                       if(!FLAC__stream_decoder_process_until_end_of_stream(stream_info.decoder.stream)) {
+                       if(!OggFLAC__stream_decoder_process_until_end_of_stream(stream_info.decoder.stream)) {
                                if(stream_info.verbose) fprintf(stderr, "\n");
-                               fprintf(stderr, "%s: ERROR while decoding data, state=%d:%s\n", stream_info.inbasefilename, FLAC__stream_decoder_get_state(stream_info.decoder.stream), FLAC__StreamDecoderStateString[FLAC__stream_decoder_get_state(stream_info.decoder.stream)]);
+                               fprintf(stderr, "%s: ERROR while decoding data, state=%d:%s\n", stream_info.inbasefilename, OggFLAC__stream_decoder_get_state(stream_info.decoder.stream), FLAC__StreamDecoderStateString[OggFLAC__stream_decoder_get_state(stream_info.decoder.stream)]);
                                goto wav_abort_;
                        }
-                       if(FLAC__stream_decoder_get_state(stream_info.decoder.stream) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA && FLAC__stream_decoder_get_state(stream_info.decoder.stream) != FLAC__STREAM_DECODER_END_OF_STREAM) {
+                       if(OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(stream_info.decoder.stream) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA && OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(stream_info.decoder.stream) != FLAC__STREAM_DECODER_END_OF_STREAM) {
                                if(stream_info.verbose) fprintf(stderr, "\n");
-                               fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", stream_info.inbasefilename, FLAC__stream_decoder_get_state(stream_info.decoder.stream), FLAC__StreamDecoderStateString[FLAC__stream_decoder_get_state(stream_info.decoder.stream)]);
+                               fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", stream_info.inbasefilename, OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(stream_info.decoder.stream), FLAC__StreamDecoderStateString[OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(stream_info.decoder.stream)]);
                                goto wav_abort_;
                        }
                }
@@ -218,10 +210,10 @@ int flac__decode_wav(const char *infilename, const char *outfilename, FLAC__bool
 #ifdef FLAC__HAS_OGG
        if(stream_info.is_ogg) {
                if(stream_info.decoder.stream) {
-                       FLAC__stream_decoder_finish(stream_info.decoder.stream);
+                       OggFLAC__stream_decoder_finish(stream_info.decoder.stream);
                        md5_failure = false;
                        print_stats(&stream_info);
-                       FLAC__stream_decoder_delete(stream_info.decoder.stream);
+                       OggFLAC__stream_decoder_delete(stream_info.decoder.stream);
                }
        }
        else
@@ -258,8 +250,8 @@ wav_abort_:
 #ifdef FLAC__HAS_OGG
        if(stream_info.is_ogg) {
                if(stream_info.decoder.stream) {
-                       FLAC__stream_decoder_finish(stream_info.decoder.stream);
-                       FLAC__stream_decoder_delete(stream_info.decoder.stream);
+                       OggFLAC__stream_decoder_finish(stream_info.decoder.stream);
+                       OggFLAC__stream_decoder_delete(stream_info.decoder.stream);
                }
        }
        else
@@ -376,14 +368,14 @@ int flac__decode_raw(const char *infilename, const char *outfilename, FLAC__bool
        else {
 #ifdef FLAC__HAS_OGG
                if(stream_info.is_ogg) {
-                       if(!FLAC__stream_decoder_process_until_end_of_stream(stream_info.decoder.stream)) {
+                       if(!OggFLAC__stream_decoder_process_until_end_of_stream(stream_info.decoder.stream)) {
                                if(stream_info.verbose) fprintf(stderr, "\n");
-                               fprintf(stderr, "%s: ERROR while decoding data, state=%d:%s\n", stream_info.inbasefilename, FLAC__stream_decoder_get_state(stream_info.decoder.stream), FLAC__StreamDecoderStateString[FLAC__stream_decoder_get_state(stream_info.decoder.stream)]);
+                               fprintf(stderr, "%s: ERROR while decoding data, state=%d:%s\n", stream_info.inbasefilename, OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(stream_info.decoder.stream), FLAC__StreamDecoderStateString[OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(stream_info.decoder.stream)]);
                                goto raw_abort_;
                        }
-                       if(FLAC__stream_decoder_get_state(stream_info.decoder.stream) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA && FLAC__stream_decoder_get_state(stream_info.decoder.stream) != FLAC__STREAM_DECODER_END_OF_STREAM) {
+                       if(OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(stream_info.decoder.stream) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA && OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(stream_info.decoder.stream) != FLAC__STREAM_DECODER_END_OF_STREAM) {
                                if(stream_info.verbose) fprintf(stderr, "\n");
-                               fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", stream_info.inbasefilename, FLAC__stream_decoder_get_state(stream_info.decoder.stream), FLAC__StreamDecoderStateString[FLAC__stream_decoder_get_state(stream_info.decoder.stream)]);
+                               fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", stream_info.inbasefilename, OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(stream_info.decoder.stream), FLAC__StreamDecoderStateString[OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(stream_info.decoder.stream)]);
                                goto raw_abort_;
                        }
                }
@@ -406,10 +398,10 @@ int flac__decode_raw(const char *infilename, const char *outfilename, FLAC__bool
 #ifdef FLAC__HAS_OGG
        if(stream_info.is_ogg) {
                if(stream_info.decoder.stream) {
-                       FLAC__stream_decoder_finish(stream_info.decoder.stream);
+                       OggFLAC__stream_decoder_finish(stream_info.decoder.stream);
                        md5_failure = false;
                        print_stats(&stream_info);
-                       FLAC__stream_decoder_delete(stream_info.decoder.stream);
+                       OggFLAC__stream_decoder_delete(stream_info.decoder.stream);
                }
        }
        else
@@ -443,8 +435,8 @@ raw_abort_:
 #ifdef FLAC__HAS_OGG
        if(stream_info.is_ogg) {
                if(stream_info.decoder.stream) {
-                       FLAC__stream_decoder_finish(stream_info.decoder.stream);
-                       FLAC__stream_decoder_delete(stream_info.decoder.stream);
+                       OggFLAC__stream_decoder_finish(stream_info.decoder.stream);
+                       OggFLAC__stream_decoder_delete(stream_info.decoder.stream);
                }
        }
        else
@@ -478,31 +470,28 @@ FLAC__bool init(const char *infilename, stream_info_struct *stream_info)
 
 #ifdef FLAC__HAS_OGG
        if(stream_info->is_ogg) {
-               stream_info->decoder.stream = FLAC__stream_decoder_new();
+               stream_info->decoder.stream = OggFLAC__stream_decoder_new();
 
                if(0 == stream_info->decoder.stream) {
                        fprintf(stderr, "%s: ERROR creating the decoder instance\n", stream_info->inbasefilename);
                        return false;
                }
 
-               FLAC__stream_decoder_set_read_callback(stream_info->decoder.stream, read_callback);
+               OggFLAC__stream_decoder_set_read_callback(stream_info->decoder.stream, read_callback);
                /*
                 * The three ugly casts here are to 'downcast' the 'void *' argument of
                 * the callback down to 'FLAC__StreamDecoder *'.  In C++ this would be
                 * unnecessary but here the cast makes the C compiler happy.
                 */
-               FLAC__stream_decoder_set_write_callback(stream_info->decoder.stream, (FLAC__StreamDecoderWriteStatus (*)(const FLAC__StreamDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *))write_callback);
-               FLAC__stream_decoder_set_metadata_callback(stream_info->decoder.stream, (void (*)(const FLAC__StreamDecoder *, const FLAC__StreamMetadata *, void *))metadata_callback);
-               FLAC__stream_decoder_set_error_callback(stream_info->decoder.stream, (void (*)(const FLAC__StreamDecoder *, FLAC__StreamDecoderErrorStatus, void *))error_callback);
-               FLAC__stream_decoder_set_client_data(stream_info->decoder.stream, stream_info);
+               OggFLAC__stream_decoder_set_write_callback(stream_info->decoder.stream, (FLAC__StreamDecoderWriteStatus (*)(const OggFLAC__StreamDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *))write_callback);
+               OggFLAC__stream_decoder_set_metadata_callback(stream_info->decoder.stream, (void (*)(const OggFLAC__StreamDecoder *, const FLAC__StreamMetadata *, void *))metadata_callback);
+               OggFLAC__stream_decoder_set_error_callback(stream_info->decoder.stream, (void (*)(const OggFLAC__StreamDecoder *, FLAC__StreamDecoderErrorStatus, void *))error_callback);
+               OggFLAC__stream_decoder_set_client_data(stream_info->decoder.stream, stream_info);
 
-               if(FLAC__stream_decoder_init(stream_info->decoder.stream) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) {
-                       fprintf(stderr, "%s: ERROR initializing decoder, state=%d:%s\n", stream_info->inbasefilename, FLAC__stream_decoder_get_state(stream_info->decoder.stream), FLAC__StreamDecoderStateString[FLAC__stream_decoder_get_state(stream_info->decoder.stream)]);
+               if(OggFLAC__stream_decoder_init(stream_info->decoder.stream) != OggFLAC__STREAM_DECODER_OK) {
+                       fprintf(stderr, "%s: ERROR initializing decoder, state=%d:%s\n", stream_info->inbasefilename, OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(stream_info->decoder.stream), FLAC__StreamDecoderStateString[OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(stream_info->decoder.stream)]);
                        return false;
                }
-
-               ogg_stream_init(&stream_info->ogg.os, 0);
-               ogg_sync_init(&stream_info->ogg.oy);
        }
        else
 #endif
@@ -587,49 +576,26 @@ FLAC__bool fixup_wave_chunk_size(const char *outfilename, unsigned riff_offset,
 }
 
 #ifdef FLAC__HAS_OGG
-#define OGG_READ_BUFFER_SIZE 4096
-FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
+FLAC__StreamDecoderReadStatus read_callback(const OggFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
 {
        stream_info_struct *stream_info = (stream_info_struct *)client_data;
        FILE *fin = stream_info->fin;
        size_t bytes_read;
-       ogg_page og;
-       char *oggbuf;
-       unsigned int offset = 0;
 
-       *bytes = 0;
+       (void)decoder; /* avoid compiler warning */
 
        if (stream_info->abort_flag)
                return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
 
-       oggbuf = ogg_sync_buffer(&stream_info->ogg.oy, OGG_READ_BUFFER_SIZE);
-
-       (void)decoder; /* avoid compiler warning */
-
        if(feof(fin))
                return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
 
-       bytes_read = fread(oggbuf, 1, OGG_READ_BUFFER_SIZE, fin);
+       bytes_read = fread(buffer, 1, *bytes, fin);
 
        if(ferror(fin))
                return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
 
-       if(ogg_sync_wrote(&stream_info->ogg.oy, bytes_read) < 0)
-               return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
-
-       while(ogg_sync_pageout(&stream_info->ogg.oy, &og) == 1) {
-               if(ogg_stream_pagein(&stream_info->ogg.os, &og) == 0) {
-                       ogg_packet op;
-
-                       while(ogg_stream_packetout(&stream_info->ogg.os, &op) == 1) {
-                               memcpy(buffer + offset, op.packet, op.bytes);
-                               *bytes += op.bytes;
-                               offset += op.bytes;
-                       }
-               } else {
-                       return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
-               }
-       }
+       *bytes = (unsigned)bytes_read;
 
        return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
 }
@@ -855,111 +821,3 @@ void print_stats(const stream_info_struct *stream_info)
                }
        }
 }
-#if 0
-void metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
-{
-       encoder_wrapper_struct *encoder_wrapper = (encoder_wrapper_struct *)client_data;
-       FLAC__byte b;
-       FILE *f = encoder_wrapper->fout;
-       const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
-       const unsigned min_framesize = metadata->data.stream_info.min_framesize;
-       const unsigned max_framesize = metadata->data.stream_info.max_framesize;
-
-       FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
-
-       /*
-        * If we are writing to an ogg stream, there is no need to go back
-        * and update the STREAMINFO or SEEKTABLE blocks; the values we would
-        * update are not necessary with Ogg as the transport.  We can't do
-        * it reliably anyway without knowing the Ogg structure.
-        */
-#ifdef FLAC__HAS_OGG
-       if(encoder_wrapper->use_ogg)
-               return;
-#endif
-
-       /*
-        * we get called by the encoder when the encoding process has
-        * finished so that we can update the STREAMINFO and SEEKTABLE
-        * blocks.
-        */
-
-       (void)encoder; /* silence compiler warning about unused parameter */
-
-       if(f != stdout) {
-               fclose(encoder_wrapper->fout);
-               if(0 == (f = fopen(encoder_wrapper->outfilename, "r+b")))
-                       return;
-       }
-
-       /* all this is based on intimate knowledge of the stream header
-        * layout, but a change to the header format that would break this
-        * would also break all streams encoded in the previous format.
-        */
-
-       if(-1 == fseek(f, 26, SEEK_SET)) goto end_;
-       fwrite(metadata->data.stream_info.md5sum, 1, 16, f);
-
-samples_:
-       /* if we get this far we know we can seek so no need to check the
-        * return value from fseek()
-        */
-       fseek(f, 21, SEEK_SET);
-       if(fread(&b, 1, 1, f) != 1) goto framesize_;
-       fseek(f, 21, SEEK_SET);
-       b = (b & 0xf0) | (FLAC__byte)((samples >> 32) & 0x0F);
-       if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
-       b = (FLAC__byte)((samples >> 24) & 0xFF);
-       if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
-       b = (FLAC__byte)((samples >> 16) & 0xFF);
-       if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
-       b = (FLAC__byte)((samples >> 8) & 0xFF);
-       if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
-       b = (FLAC__byte)(samples & 0xFF);
-       if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
-
-framesize_:
-       fseek(f, 12, SEEK_SET);
-       b = (FLAC__byte)((min_framesize >> 16) & 0xFF);
-       if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
-       b = (FLAC__byte)((min_framesize >> 8) & 0xFF);
-       if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
-       b = (FLAC__byte)(min_framesize & 0xFF);
-       if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
-       b = (FLAC__byte)((max_framesize >> 16) & 0xFF);
-       if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
-       b = (FLAC__byte)((max_framesize >> 8) & 0xFF);
-       if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
-       b = (FLAC__byte)(max_framesize & 0xFF);
-       if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
-
-seektable_:
-       if(encoder_wrapper->seek_table.num_points > 0) {
-               long pos;
-               unsigned i;
-
-               /* convert any unused seek points to placeholders */
-               for(i = 0; i < encoder_wrapper->seek_table.num_points; i++) {
-                       if(encoder_wrapper->seek_table.points[i].sample_number == FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER)
-                               break;
-                       else if(encoder_wrapper->seek_table.points[i].frame_samples == 0)
-                               encoder_wrapper->seek_table.points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
-               }
-
-               /* the offset of the seek table data 'pos' should be after then stream sync and STREAMINFO block and SEEKTABLE header */
-               pos = (FLAC__STREAM_SYNC_LEN + FLAC__STREAM_METADATA_IS_LAST_LEN + FLAC__STREAM_METADATA_TYPE_LEN + FLAC__STREAM_METADATA_LENGTH_LEN) / 8;
-               pos += metadata->length;
-               pos += (FLAC__STREAM_METADATA_IS_LAST_LEN + FLAC__STREAM_METADATA_TYPE_LEN + FLAC__STREAM_METADATA_LENGTH_LEN) / 8;
-               fseek(f, pos, SEEK_SET);
-               for(i = 0; i < encoder_wrapper->seek_table.num_points; i++) {
-                       if(!write_big_endian_uint64(f, encoder_wrapper->seek_table.points[i].sample_number)) goto end_;
-                       if(!write_big_endian_uint64(f, encoder_wrapper->seek_table.points[i].stream_offset)) goto end_;
-                       if(!write_big_endian_uint16(f, (FLAC__uint16)encoder_wrapper->seek_table.points[i].frame_samples)) goto end_;
-               }
-       }
-
-end_:
-       fclose(f);
-       return;
-}
-#endif