From 8304c8fdac951b135902c274c0703b4ccddbd425 Mon Sep 17 00:00:00 2001 From: Josh Coalson Date: Wed, 4 Sep 2002 07:52:58 +0000 Subject: [PATCH] add support for serial number in Ogg streams --- include/OggFLAC++/decoder.h | 1 + include/OggFLAC++/encoder.h | 1 + include/OggFLAC/file_decoder.h | 10 +++++---- include/OggFLAC/seekable_stream_decoder.h | 16 ++++++++------ include/OggFLAC/stream_decoder.h | 27 ++++++++++++++++++----- include/OggFLAC/stream_encoder.h | 12 ++++++++++ src/flac/decode.c | 19 ++++++++++------ src/flac/decode.h | 2 ++ src/flac/encode.c | 2 ++ src/flac/encode.h | 2 ++ src/flac/main.c | 21 ++++++++++++++++-- src/libOggFLAC++/stream_decoder.cc | 6 +++++ src/libOggFLAC++/stream_encoder.cc | 6 +++++ src/libOggFLAC/include/protected/stream_decoder.h | 2 ++ src/libOggFLAC/include/protected/stream_encoder.h | 1 + src/libOggFLAC/stream_decoder.c | 23 ++++++++++++++++++- src/libOggFLAC/stream_encoder.c | 15 ++++++++++++- src/test_libOggFLAC++/decoders.cc | 5 +++++ src/test_libOggFLAC++/encoders.cc | 5 +++++ src/test_libOggFLAC++/file_utils.c | 3 +++ src/test_libOggFLAC++/file_utils.h | 2 ++ src/test_libOggFLAC/decoders.c | 5 +++++ src/test_libOggFLAC/encoders.c | 5 +++++ src/test_libOggFLAC/file_utils.c | 3 +++ src/test_libOggFLAC/file_utils.h | 2 ++ 25 files changed, 168 insertions(+), 28 deletions(-) diff --git a/include/OggFLAC++/decoder.h b/include/OggFLAC++/decoder.h index 000f015..3f320ff 100644 --- a/include/OggFLAC++/decoder.h +++ b/include/OggFLAC++/decoder.h @@ -91,6 +91,7 @@ namespace OggFLAC { bool is_valid() const; inline operator bool() const { return is_valid(); } + bool set_serial_number(long value); bool set_metadata_respond(::FLAC__MetadataType type); bool set_metadata_respond_application(const FLAC__byte id[4]); bool set_metadata_respond_all(); diff --git a/include/OggFLAC++/encoder.h b/include/OggFLAC++/encoder.h index 632ba8d..c74f1c7 100644 --- a/include/OggFLAC++/encoder.h +++ b/include/OggFLAC++/encoder.h @@ -93,6 +93,7 @@ namespace OggFLAC { bool is_valid() const; inline operator bool() const { return is_valid(); } + bool set_serial_number(long value); bool set_verify(bool value); bool set_streamable_subset(bool value); bool set_do_mid_side_stereo(bool value); diff --git a/include/OggFLAC/file_decoder.h b/include/OggFLAC/file_decoder.h index 246c819..80d8499 100644 --- a/include/OggFLAC/file_decoder.h +++ b/include/OggFLAC/file_decoder.h @@ -143,6 +143,8 @@ void OggFLAC__file_decoder_delete(OggFLAC__FileDecoder *decoder); * ***********************************************************************/ +/*@@@inherit set_serial_number*/ + /** Set the "MD5 signature checking" flag. * This is inherited from FLAC__FileDecoder; see * FLAC__file_decoder_set_md5_checking(). @@ -232,7 +234,7 @@ FLAC__bool OggFLAC__file_decoder_set_error_callback(OggFLAC__FileDecoder *decode * argument. * * \default \c NULL - * \param decoder An decoder instance to set. + * \param decoder A decoder instance to set. * \param value See above. * \assert * \code decoder != NULL \endcode @@ -341,7 +343,7 @@ OggFLAC__FileDecoderState OggFLAC__file_decoder_get_state(const OggFLAC__FileDec * Useful when the file decoder state is * \c OggFLAC__FILE_DECODER_FLAC_FILE_DECODER_ERROR. * - * \param decoder An decoder instance to query. + * \param decoder A decoder instance to query. * \assert * \code decoder != NULL \endcode * \retval FLAC__FileDecoderState @@ -354,7 +356,7 @@ FLAC__FileDecoderState OggFLAC__file_decoder_get_FLAC_file_decoder_state(const O * \c OggFLAC__FILE_DECODER_FLAC_FILE_DECODER_ERROR and the FLAC file decoder state is * \c FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR. * - * \param decoder An decoder instance to query. + * \param decoder A decoder instance to query. * \assert * \code decoder != NULL \endcode * \retval FLAC__SeekableStreamDecoderState @@ -368,7 +370,7 @@ FLAC__SeekableStreamDecoderState OggFLAC__file_decoder_get_FLAC_seekable_stream_ * \c FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR and the * FLAC seekable stream decoder state is \c FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR. * - * \param decoder An decoder instance to query. + * \param decoder A decoder instance to query. * \assert * \code decoder != NULL \endcode * \retval FLAC__StreamDecoderState diff --git a/include/OggFLAC/seekable_stream_decoder.h b/include/OggFLAC/seekable_stream_decoder.h index 3970bcc..7b5f105 100644 --- a/include/OggFLAC/seekable_stream_decoder.h +++ b/include/OggFLAC/seekable_stream_decoder.h @@ -151,6 +151,8 @@ void OggFLAC__seekable_stream_decoder_delete(OggFLAC__SeekableStreamDecoder *dec * ***********************************************************************/ +/*@@@inherit set_serial_number*/ + /** Set the "MD5 signature checking" flag. * This is inherited from FLAC__SeekableStreamDecoder; see * FLAC__seekable_stream_decoder_set_md5_checking(). @@ -191,7 +193,7 @@ FLAC__bool OggFLAC__seekable_stream_decoder_set_read_callback(OggFLAC__SeekableS * The callback is mandatory and must be set before initialization. * * \default \c NULL - * \param decoder An decoder instance to set. + * \param decoder A decoder instance to set. * \param value See above. * \assert * \code decoder != NULL \endcode @@ -209,7 +211,7 @@ FLAC__bool OggFLAC__seekable_stream_decoder_set_seek_callback(OggFLAC__SeekableS * The callback is mandatory and must be set before initialization. * * \default \c NULL - * \param decoder An decoder instance to set. + * \param decoder A decoder instance to set. * \param value See above. * \assert * \code decoder != NULL \endcode @@ -227,7 +229,7 @@ FLAC__bool OggFLAC__seekable_stream_decoder_set_tell_callback(OggFLAC__SeekableS * The callback is mandatory and must be set before initialization. * * \default \c NULL - * \param decoder An decoder instance to set. + * \param decoder A decoder instance to set. * \param value See above. * \assert * \code decoder != NULL \endcode @@ -245,7 +247,7 @@ FLAC__bool OggFLAC__seekable_stream_decoder_set_length_callback(OggFLAC__Seekabl * The callback is mandatory and must be set before initialization. * * \default \c NULL - * \param decoder An decoder instance to set. + * \param decoder A decoder instance to set. * \param value See above. * \assert * \code decoder != NULL \endcode @@ -314,7 +316,7 @@ FLAC__bool OggFLAC__seekable_stream_decoder_set_error_callback(OggFLAC__Seekable * argument. * * \default \c NULL - * \param decoder An decoder instance to set. + * \param decoder A decoder instance to set. * \param value See above. * \assert * \code decoder != NULL \endcode @@ -423,7 +425,7 @@ OggFLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_get_state(c * Useful when the seekable stream decoder state is * \c OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR. * - * \param decoder An decoder instance to query. + * \param decoder A decoder instance to query. * \assert * \code decoder != NULL \endcode * \retval FLAC__SeekableStreamDecoderState @@ -436,7 +438,7 @@ FLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_get_FLAC_seeka * \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 * - * \param decoder An decoder instance to query. + * \param decoder A decoder instance to query. * \assert * \code decoder != NULL \endcode * \retval FLAC__StreamDecoderState diff --git a/include/OggFLAC/stream_decoder.h b/include/OggFLAC/stream_decoder.h index 6c27116..fb0cbec 100644 --- a/include/OggFLAC/stream_decoder.h +++ b/include/OggFLAC/stream_decoder.h @@ -214,7 +214,7 @@ void OggFLAC__stream_decoder_delete(OggFLAC__StreamDecoder *decoder); * The callback is mandatory and must be set before initialization. * * \default \c NULL - * \param decoder An decoder instance to set. + * \param decoder A decoder instance to set. * \param value See above. * \assert * \code decoder != NULL \endcode @@ -231,7 +231,7 @@ FLAC__bool OggFLAC__stream_decoder_set_read_callback(OggFLAC__StreamDecoder *dec * The callback is mandatory and must be set before initialization. * * \default \c NULL - * \param decoder An decoder instance to set. + * \param decoder A decoder instance to set. * \param value See above. * \assert * \code decoder != NULL \endcode @@ -248,7 +248,7 @@ FLAC__bool OggFLAC__stream_decoder_set_write_callback(OggFLAC__StreamDecoder *de * The callback is mandatory and must be set before initialization. * * \default \c NULL - * \param decoder An decoder instance to set. + * \param decoder A decoder instance to set. * \param value See above. * \assert * \code decoder != NULL \endcode @@ -265,7 +265,7 @@ FLAC__bool OggFLAC__stream_decoder_set_metadata_callback(OggFLAC__StreamDecoder * The callback is mandatory and must be set before initialization. * * \default \c NULL - * \param decoder An decoder instance to set. + * \param decoder A decoder instance to set. * \param value See above. * \assert * \code decoder != NULL \endcode @@ -280,7 +280,7 @@ FLAC__bool OggFLAC__stream_decoder_set_error_callback(OggFLAC__StreamDecoder *de * argument. * * \default \c NULL - * \param decoder An decoder instance to set. + * \param decoder A decoder instance to set. * \param value See above. * \assert * \code decoder != NULL \endcode @@ -289,6 +289,21 @@ FLAC__bool OggFLAC__stream_decoder_set_error_callback(OggFLAC__StreamDecoder *de */ FLAC__bool OggFLAC__stream_decoder_set_client_data(OggFLAC__StreamDecoder *decoder, void *value); +/** Set the serial number for the Ogg stream. + * The default behavior is to use the serial number of the first Ogg + * page. Setting a serial number here will explicitly define which + * stream is to be decoded. + * + * \default \c use serial number of first page + * \param decoder A decoder instance to set. + * \param serial_number See above. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC__bool OggFLAC__stream_decoder_set_serial_number(OggFLAC__StreamDecoder *decoder, long serial_number); + /** Direct the decoder to pass on all metadata blocks of type \a type. * This is inherited from FLAC__StreamDecoder; see FLAC__stream_decoder_set_metadata_respond() * @@ -391,7 +406,7 @@ OggFLAC__StreamDecoderState OggFLAC__stream_decoder_get_state(const OggFLAC__Str * Useful when the stream decoder state is * \c OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR. * - * \param decoder An decoder instance to query. + * \param decoder A decoder instance to query. * \assert * \code decoder != NULL \endcode * \retval FLAC__StreamDecoderState diff --git a/include/OggFLAC/stream_encoder.h b/include/OggFLAC/stream_encoder.h index 28c1107..017077b 100644 --- a/include/OggFLAC/stream_encoder.h +++ b/include/OggFLAC/stream_encoder.h @@ -171,6 +171,18 @@ void OggFLAC__stream_encoder_delete(OggFLAC__StreamEncoder *encoder); * ***********************************************************************/ +/** Set the serial number for the FLAC stream. + * + * \default \c NULL, 0 + * \param encoder An encoder instance to set. + * \param serial_number See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool OggFLAC__stream_encoder_set_serial_number(OggFLAC__StreamEncoder *encoder, long serial_number); + /** This is inherited from FLAC__StreamEncoder; see FLAC__stream_encoder_set_verify() * * \default \c false diff --git a/src/flac/decode.c b/src/flac/decode.c index d5bfae4..12bc092 100644 --- a/src/flac/decode.c +++ b/src/flac/decode.c @@ -91,7 +91,7 @@ static FLAC__bool is_big_endian_host_; */ static FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool verbose, FLAC__bool is_wave_out, FLAC__bool continue_through_decode_errors, FLAC__bool analysis_mode, analysis_options aopts, FLAC__uint64 skip, const char *infilename, const char *outfilename); static void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred); -static FLAC__bool DecoderSession_init_decoder(DecoderSession *d, const char *infilename); +static FLAC__bool DecoderSession_init_decoder(DecoderSession *d, decode_options_t decode_options, const char *infilename); static FLAC__bool DecoderSession_process(DecoderSession *d); static int DecoderSession_finish_ok(DecoderSession *d); static int DecoderSession_finish_error(DecoderSession *d); @@ -140,7 +140,7 @@ int flac__decode_wav(const char *infilename, const char *outfilename, FLAC__bool ) return 1; - if(!DecoderSession_init_decoder(&decoder_session, infilename)) + if(!DecoderSession_init_decoder(&decoder_session, options.common, infilename)) return DecoderSession_finish_error(&decoder_session); if(!DecoderSession_process(&decoder_session)) @@ -176,7 +176,7 @@ int flac__decode_raw(const char *infilename, const char *outfilename, FLAC__bool ) return 1; - if(!DecoderSession_init_decoder(&decoder_session, infilename)) + if(!DecoderSession_init_decoder(&decoder_session, options.common, infilename)) return DecoderSession_finish_error(&decoder_session); if(!DecoderSession_process(&decoder_session)) @@ -268,7 +268,7 @@ void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred) #endif } -FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, const char *infilename) +FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, decode_options_t decode_options, const char *infilename) { FLAC__uint32 test = 1; @@ -283,6 +283,9 @@ FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, const ch return false; } + if(!decode_options.use_first_serial_number) + OggFLAC__stream_decoder_set_serial_number(decoder_session->decoder.ogg.stream, decode_options.serial_number); + OggFLAC__stream_decoder_set_read_callback(decoder_session->decoder.ogg.stream, read_callback); /* * The three ugly casts here are to 'downcast' the 'void *' argument of @@ -300,6 +303,8 @@ FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, const ch } } else +#else + (void)decode_options; #endif { decoder_session->decoder.flac.file = FLAC__file_decoder_new(); @@ -552,15 +557,15 @@ FLAC__StreamDecoderWriteStatus write_callback(const void *decoder, const FLAC__F return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; if(bps != decoder_session->bps) { - fprintf("ERROR, bits-per-sample is %u in frame but %u in STREAMINFO\n", bps, decoder_session->bps); + fprintf(stderr, "ERROR, bits-per-sample is %u in frame but %u in STREAMINFO\n", bps, decoder_session->bps); return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } if(channels != decoder_session->channels) { - fprintf("ERROR, channels is %u in frame but %u in STREAMINFO\n", channels, decoder_session->channels); + fprintf(stderr, "ERROR, channels is %u in frame but %u in STREAMINFO\n", channels, decoder_session->channels); return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } if(frame->header.sample_rate != decoder_session->sample_rate) { - fprintf("ERROR, sample rate is %u in frame but %u in STREAMINFO\n", frame->header.sample_rate, decoder_session->sample_rate); + fprintf(stderr, "ERROR, sample rate is %u in frame but %u in STREAMINFO\n", frame->header.sample_rate, decoder_session->sample_rate); return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } diff --git a/src/flac/decode.h b/src/flac/decode.h index 871dbc7..3e0dfa8 100644 --- a/src/flac/decode.h +++ b/src/flac/decode.h @@ -26,6 +26,8 @@ typedef struct { FLAC__bool continue_through_decode_errors; #ifdef FLAC__HAS_OGG FLAC__bool is_ogg; + FLAC__bool use_first_serial_number; + long serial_number; #endif FLAC__uint64 skip; } decode_options_t; diff --git a/src/flac/encode.c b/src/flac/encode.c index 8127ff7..4f17f1d 100644 --- a/src/flac/encode.c +++ b/src/flac/encode.c @@ -1181,6 +1181,8 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio #ifdef FLAC__HAS_OGG if(e->use_ogg) { + if(options.has_serial_number) + OggFLAC__stream_encoder_set_serial_number(e->encoder.ogg.stream, options.serial_number); OggFLAC__stream_encoder_set_verify(e->encoder.ogg.stream, options.verify); OggFLAC__stream_encoder_set_streamable_subset(e->encoder.ogg.stream, !options.lax); OggFLAC__stream_encoder_set_do_mid_side_stereo(e->encoder.ogg.stream, options.do_mid_side); diff --git a/src/flac/encode.h b/src/flac/encode.h index a2529ed..5838a13 100644 --- a/src/flac/encode.h +++ b/src/flac/encode.h @@ -27,6 +27,8 @@ typedef struct { FLAC__bool verify; #ifdef FLAC__HAS_OGG FLAC__bool use_ogg; + FLAC__bool has_serial_number; + long serial_number; #endif FLAC__bool lax; FLAC__bool do_mid_side; diff --git a/src/flac/main.c b/src/flac/main.c index be71058..6241fab 100644 --- a/src/flac/main.c +++ b/src/flac/main.c @@ -114,6 +114,7 @@ static struct FLAC__share__option long_options_[] = { { "padding", 1, 0, 'P' }, #ifdef FLAC__HAS_OGG { "ogg", 0, 0, 0 }, + { "serial-number", 1, 0, 0 }, #endif { "blocksize", 1, 0, 'b' }, { "exhaustive-model-search", 0, 0, 'e' }, @@ -188,6 +189,8 @@ static struct { FLAC__bool test_only; FLAC__bool analyze; FLAC__bool use_ogg; + FLAC__bool has_serial_number; /* true iff --serial-number was used */ + long serial_number; /* this is the Ogg serial number and is unused for native FLAC */ FLAC__bool do_mid_side; FLAC__bool loose_mid_side; FLAC__bool do_exhaustive_model_search; @@ -374,9 +377,7 @@ int do_it() "%s -P%s -b %u%s -l %u%s%s%s -q %u -r %u,%u%s\n", option_values.delete_input?" --delete-input-file":"", option_values.sector_align?" --sector-align":"", -#ifdef FLAC__HAS_OGG option_values.use_ogg?" --ogg":"", -#endif option_values.lax?" --lax":"", padopt, (unsigned)option_values.blocksize, @@ -445,6 +446,8 @@ void init_options() option_values.test_only = false; option_values.analyze = false; option_values.use_ogg = false; + option_values.has_serial_number = false; + option_values.serial_number = 0; option_values.do_mid_side = true; option_values.loose_mid_side = false; option_values.do_exhaustive_model_search = false; @@ -561,6 +564,10 @@ int parse_option(int short_option, const char *long_option, const char *option_a else if(0 == strcmp(long_option, "ogg")) { option_values.use_ogg = true; } + else if(0 == strcmp(long_option, "serial-number")) { + option_values.has_serial_number = true; + option_values.serial_number = atol(option_argument); + } #endif else if(0 == strcmp(long_option, "endian")) { FLAC__ASSERT(0 != option_argument); @@ -962,6 +969,7 @@ void show_help() printf(" -V, --verify Verify a correct encoding\n"); #ifdef FLAC__HAS_OGG printf(" --ogg Use Ogg as transport layer\n"); + printf(" --serial-number Serial number to use for the FLAC stream\n"); #endif printf(" --lax Allow encoder to generate non-Subset files\n"); printf(" --sector-align Align multiple files on sector boundaries\n"); @@ -1098,6 +1106,11 @@ void show_explain() printf(" Ogg-FLAC. This is useful when piping input\n"); printf(" from stdin or when the filename does not end in\n"); printf(" '.ogg'.\n"); + printf(" --serial-number Serial number to use for the FLAC stream. When\n"); + printf(" encoding and no serial number is given, flac\n"); + printf(" uses '0'. When decoding and no number is\n"); + printf(" given, flac uses the serial number of the first\n"); + printf(" page.\n"); #endif printf(" --lax Allow encoder to generate non-Subset files\n"); printf(" --sector-align Align encoding of multiple CD format WAVE files\n"); @@ -1299,6 +1312,8 @@ int encode_file(const char *infilename, const char *forced_outfilename, FLAC__bo common_options.verify = option_values.verify; #ifdef FLAC__HAS_OGG common_options.use_ogg = option_values.use_ogg; + common_options.has_serial_number = option_values.has_serial_number; + common_options.serial_number = option_values.serial_number; #endif common_options.lax = option_values.lax; common_options.do_mid_side = option_values.do_mid_side; @@ -1407,6 +1422,8 @@ int decode_file(const char *infilename, const char *forced_outfilename) common_options.continue_through_decode_errors = option_values.continue_through_decode_errors; #ifdef FLAC__HAS_OGG common_options.is_ogg = treat_as_ogg; + common_options.use_first_serial_number = !option_values.has_serial_number; + common_options.serial_number = option_values.serial_number; #endif common_options.skip = option_values.skip; diff --git a/src/libOggFLAC++/stream_decoder.cc b/src/libOggFLAC++/stream_decoder.cc index ad44142..82bec7a 100644 --- a/src/libOggFLAC++/stream_decoder.cc +++ b/src/libOggFLAC++/stream_decoder.cc @@ -40,6 +40,12 @@ namespace OggFLAC { return 0 != decoder_; } + bool Stream::set_serial_number(long value) + { + FLAC__ASSERT(is_valid()); + return (bool)::OggFLAC__stream_decoder_set_serial_number(decoder_, value); + } + bool Stream::set_metadata_respond(::FLAC__MetadataType type) { FLAC__ASSERT(is_valid()); diff --git a/src/libOggFLAC++/stream_encoder.cc b/src/libOggFLAC++/stream_encoder.cc index 33367d3..1ac3037 100644 --- a/src/libOggFLAC++/stream_encoder.cc +++ b/src/libOggFLAC++/stream_encoder.cc @@ -40,6 +40,12 @@ namespace OggFLAC { return 0 != encoder_; } + bool Stream::set_serial_number(long value) + { + FLAC__ASSERT(is_valid()); + return (bool)::OggFLAC__stream_encoder_set_serial_number(encoder_, value); + } + bool Stream::set_verify(bool value) { FLAC__ASSERT(is_valid()); diff --git a/src/libOggFLAC/include/protected/stream_decoder.h b/src/libOggFLAC/include/protected/stream_decoder.h index 833fa51..6a57986 100644 --- a/src/libOggFLAC/include/protected/stream_decoder.h +++ b/src/libOggFLAC/include/protected/stream_decoder.h @@ -24,6 +24,8 @@ typedef struct OggFLAC__StreamDecoderProtected { OggFLAC__StreamDecoderState state; + FLAC__bool use_first_serial_number; + long serial_number; } OggFLAC__StreamDecoderProtected; #endif diff --git a/src/libOggFLAC/include/protected/stream_encoder.h b/src/libOggFLAC/include/protected/stream_encoder.h index aaa7d1d..7c8091c 100644 --- a/src/libOggFLAC/include/protected/stream_encoder.h +++ b/src/libOggFLAC/include/protected/stream_encoder.h @@ -24,6 +24,7 @@ typedef struct OggFLAC__StreamEncoderProtected { OggFLAC__StreamEncoderState state; + long serial_number; } OggFLAC__StreamEncoderProtected; #endif diff --git a/src/libOggFLAC/stream_decoder.c b/src/libOggFLAC/stream_decoder.c index 41e6803..4c9d595 100644 --- a/src/libOggFLAC/stream_decoder.c +++ b/src/libOggFLAC/stream_decoder.c @@ -57,6 +57,7 @@ typedef struct OggFLAC__StreamDecoderPrivate { struct { ogg_stream_state stream_state; ogg_sync_state sync_state; + FLAC__bool need_serial_number; } ogg; } OggFLAC__StreamDecoderPrivate; @@ -155,7 +156,9 @@ OggFLAC__StreamDecoderState OggFLAC__stream_decoder_init(OggFLAC__StreamDecoder 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 = OggFLAC__STREAM_DECODER_INVALID_CALLBACK; - if(ogg_stream_init(&decoder->private_->ogg.stream_state, 0) != 0) + decoder->private_->ogg.need_serial_number = decoder->protected_->use_first_serial_number; + /* we will determine the serial number later if necessary */ + if(ogg_stream_init(&decoder->private_->ogg.stream_state, decoder->protected_->serial_number) != 0) return decoder->protected_->state = OggFLAC__STREAM_DECODER_OGG_ERROR; if(ogg_sync_init(&decoder->private_->ogg.sync_state) != 0) @@ -249,6 +252,18 @@ FLAC__bool OggFLAC__stream_decoder_set_client_data(OggFLAC__StreamDecoder *decod return true; } +FLAC__bool OggFLAC__stream_decoder_set_serial_number(OggFLAC__StreamDecoder *decoder, long 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->protected_->use_first_serial_number = false; + decoder->protected_->serial_number = value; + return true; +} + FLAC__bool OggFLAC__stream_decoder_set_metadata_respond(OggFLAC__StreamDecoder *decoder, FLAC__MetadataType type) { FLAC__ASSERT(0 != decoder); @@ -432,6 +447,7 @@ void set_defaults_(OggFLAC__StreamDecoder *decoder) decoder->private_->metadata_callback = 0; decoder->private_->error_callback = 0; decoder->private_->client_data = 0; + decoder->protected_->use_first_serial_number = true; } FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *unused, FLAC__byte buffer[], unsigned *bytes, void *client_data) @@ -466,6 +482,11 @@ FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *unused, *bytes = 0; while(ogg_sync_pageout(&decoder->private_->ogg.sync_state, &page) == 1) { + /* grab the serial number if necessary */ + if(decoder->private_->ogg.need_serial_number) { + decoder->private_->ogg.stream_state.serialno = decoder->protected_->serial_number = ogg_page_serialno(&page); + decoder->private_->ogg.need_serial_number = false; + } if(ogg_stream_pagein(&decoder->private_->ogg.stream_state, &page) == 0) { ogg_packet packet; diff --git a/src/libOggFLAC/stream_encoder.c b/src/libOggFLAC/stream_encoder.c index f949ace..24fcc67 100644 --- a/src/libOggFLAC/stream_encoder.c +++ b/src/libOggFLAC/stream_encoder.c @@ -151,7 +151,7 @@ OggFLAC__StreamEncoderState OggFLAC__stream_encoder_init(OggFLAC__StreamEncoder if(0 == encoder->private_->write_callback) return encoder->protected_->state = OggFLAC__STREAM_ENCODER_INVALID_CALLBACK; - if(ogg_stream_init(&encoder->private_->ogg.stream_state, /*@@@serialno=*/0) != 0) + if(ogg_stream_init(&encoder->private_->ogg.stream_state, encoder->protected_->serial_number) != 0) return encoder->protected_->state = OggFLAC__STREAM_ENCODER_OGG_ERROR; FLAC__stream_encoder_set_write_callback(encoder->private_->FLAC_stream_encoder, write_callback_); @@ -187,6 +187,18 @@ void OggFLAC__stream_encoder_finish(OggFLAC__StreamEncoder *encoder) encoder->protected_->state = OggFLAC__STREAM_ENCODER_UNINITIALIZED; } +FLAC__bool OggFLAC__stream_encoder_set_serial_number(OggFLAC__StreamEncoder *encoder, long 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__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->serial_number = value; + return true; +} + FLAC__bool OggFLAC__stream_encoder_set_verify(OggFLAC__StreamEncoder *encoder, FLAC__bool value) { FLAC__ASSERT(0 != encoder); @@ -603,6 +615,7 @@ void set_defaults_(OggFLAC__StreamEncoder *encoder) encoder->private_->write_callback = 0; encoder->private_->client_data = 0; + encoder->protected_->serial_number = 0; } FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *unused, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data) diff --git a/src/test_libOggFLAC++/decoders.cc b/src/test_libOggFLAC++/decoders.cc index a56fc25..ea7a46b 100644 --- a/src/test_libOggFLAC++/decoders.cc +++ b/src/test_libOggFLAC++/decoders.cc @@ -388,6 +388,11 @@ static bool test_stream_decoder() } printf("OK\n"); + printf("testing set_serial_number()... "); + if(!decoder->set_serial_number(file_utils__serial_number)) + return decoder->die("returned false"); + printf("OK\n"); + printf("testing init()... "); if(decoder->init() != ::OggFLAC__STREAM_DECODER_OK) return decoder->die(); diff --git a/src/test_libOggFLAC++/encoders.cc b/src/test_libOggFLAC++/encoders.cc index f30941c..802f987 100644 --- a/src/test_libOggFLAC++/encoders.cc +++ b/src/test_libOggFLAC++/encoders.cc @@ -181,6 +181,11 @@ static bool test_stream_encoder() } printf("OK\n"); + printf("testing set_serial_number()... "); + if(!encoder->set_serial_number(file_utils__serial_number)) + return encoder->die("returned false"); + printf("OK\n"); + printf("testing set_verify()... "); if(!encoder->set_verify(true)) return encoder->die("returned false"); diff --git a/src/test_libOggFLAC++/file_utils.c b/src/test_libOggFLAC++/file_utils.c index 2f8e7c7..a3481f3 100644 --- a/src/test_libOggFLAC++/file_utils.c +++ b/src/test_libOggFLAC++/file_utils.c @@ -35,6 +35,8 @@ #endif #define min(a,b) ((a)<(b)?(a):(b)) +const long file_utils__serial_number = 12345; + typedef struct { FILE *file; } encoder_client_struct; @@ -108,6 +110,7 @@ FLAC__bool file_utils__generate_oggflacfile(const char *output_filename, unsigne return false; } + OggFLAC__stream_encoder_set_serial_number(encoder, file_utils__serial_number); OggFLAC__stream_encoder_set_verify(encoder, true); OggFLAC__stream_encoder_set_streamable_subset(encoder, true); OggFLAC__stream_encoder_set_do_mid_side_stereo(encoder, false); diff --git a/src/test_libOggFLAC++/file_utils.h b/src/test_libOggFLAC++/file_utils.h index 3a20403..ef73f26 100644 --- a/src/test_libOggFLAC++/file_utils.h +++ b/src/test_libOggFLAC++/file_utils.h @@ -21,6 +21,8 @@ #include "FLAC/format.h" +extern const long file_utils__serial_number; + FLAC__bool file_utils__change_stats(const char *filename, FLAC__bool read_only); FLAC__bool file_utils__remove_file(const char *filename); diff --git a/src/test_libOggFLAC/decoders.c b/src/test_libOggFLAC/decoders.c index 2db275d..e64113b 100644 --- a/src/test_libOggFLAC/decoders.c +++ b/src/test_libOggFLAC/decoders.c @@ -364,6 +364,11 @@ static FLAC__bool test_stream_decoder() } printf("OK\n"); + printf("testing OggFLAC__stream_decoder_set_serial_number()... "); + if(!OggFLAC__stream_decoder_set_serial_number(decoder, file_utils__serial_number)) + return die_s_("returned false", decoder); + printf("OK\n"); + printf("testing OggFLAC__stream_decoder_set_read_callback()... "); if(!OggFLAC__stream_decoder_set_read_callback(decoder, stream_decoder_read_callback_)) return die_s_("returned false", decoder); diff --git a/src/test_libOggFLAC/encoders.c b/src/test_libOggFLAC/encoders.c index 8572829..388b409 100644 --- a/src/test_libOggFLAC/encoders.c +++ b/src/test_libOggFLAC/encoders.c @@ -164,6 +164,11 @@ static FLAC__bool test_stream_encoder() } printf("OK\n"); + printf("testing OggFLAC__stream_encoder_set_serial_number()... "); + if(!OggFLAC__stream_encoder_set_serial_number(encoder, file_utils__serial_number)) + return die_s_("returned false", encoder); + printf("OK\n"); + printf("testing OggFLAC__stream_encoder_set_verify()... "); if(!OggFLAC__stream_encoder_set_verify(encoder, true)) return die_s_("returned false", encoder); diff --git a/src/test_libOggFLAC/file_utils.c b/src/test_libOggFLAC/file_utils.c index 2f8e7c7..a3481f3 100644 --- a/src/test_libOggFLAC/file_utils.c +++ b/src/test_libOggFLAC/file_utils.c @@ -35,6 +35,8 @@ #endif #define min(a,b) ((a)<(b)?(a):(b)) +const long file_utils__serial_number = 12345; + typedef struct { FILE *file; } encoder_client_struct; @@ -108,6 +110,7 @@ FLAC__bool file_utils__generate_oggflacfile(const char *output_filename, unsigne return false; } + OggFLAC__stream_encoder_set_serial_number(encoder, file_utils__serial_number); OggFLAC__stream_encoder_set_verify(encoder, true); OggFLAC__stream_encoder_set_streamable_subset(encoder, true); OggFLAC__stream_encoder_set_do_mid_side_stereo(encoder, false); diff --git a/src/test_libOggFLAC/file_utils.h b/src/test_libOggFLAC/file_utils.h index 3a20403..ef73f26 100644 --- a/src/test_libOggFLAC/file_utils.h +++ b/src/test_libOggFLAC/file_utils.h @@ -21,6 +21,8 @@ #include "FLAC/format.h" +extern const long file_utils__serial_number; + FLAC__bool file_utils__change_stats(const char *filename, FLAC__bool read_only); FLAC__bool file_utils__remove_file(const char *filename); -- 2.7.4