From 8bd4884ca184c2ce667d91b1f89eade1132b2e21 Mon Sep 17 00:00:00 2001 From: Josh Coalson Date: Wed, 24 Sep 2003 22:03:35 +0000 Subject: [PATCH] add the metadata callback back in the stream encoder --- include/OggFLAC++/encoder.h | 2 ++ include/OggFLAC/stream_encoder.h | 42 ++++++++++++++++++++++++++++++++----- src/libOggFLAC++/stream_encoder.cpp | 10 +++++++++ src/libOggFLAC/stream_encoder.c | 31 +++++++++++++++++++-------- src/test_libOggFLAC++/encoders.cpp | 6 ++++++ src/test_libOggFLAC/encoders.c | 11 ++++++++++ 6 files changed, 88 insertions(+), 14 deletions(-) diff --git a/include/OggFLAC++/encoder.h b/include/OggFLAC++/encoder.h index 96721e2..b92145f 100644 --- a/include/OggFLAC++/encoder.h +++ b/include/OggFLAC++/encoder.h @@ -158,10 +158,12 @@ namespace OggFLAC { bool process_interleaved(const FLAC__int32 buffer[], unsigned samples); protected: virtual ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame) = 0; + virtual void metadata_callback(const FLAC__StreamMetadata *metadata) = 0; ::OggFLAC__StreamEncoder *encoder_; private: static ::FLAC__StreamEncoderWriteStatus write_callback_(const ::OggFLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data); + static void metadata_callback_(const ::OggFLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data); // Private and undefined so you can't use them: Stream(const Stream &); diff --git a/include/OggFLAC/stream_encoder.h b/include/OggFLAC/stream_encoder.h index 559f2f6..c5d05e8 100644 --- a/include/OggFLAC/stream_encoder.h +++ b/include/OggFLAC/stream_encoder.h @@ -55,10 +55,11 @@ extern "C" { * \ingroup oggflac * * \brief - * This module describes the encoder layers provided by libOggFLAC. + * This module describes the three encoder layers provided by libOggFLAC. * - * libOggFLAC currently provides the same stream layer access as libFLAC; - * the interface is nearly identical. See the \link flac_encoder FLAC + * libOggFLAC currently provides the same three layers of access as libFLAC; + * the interfaces are nearly identical, with the addition of a method for + * specifying the Ogg serial number. See the \link flac_encoder FLAC * encoder module \endlink for full documentation. */ @@ -70,8 +71,10 @@ extern "C" { * encoder. * * The interface here is nearly identical to FLAC's stream encoder, - * including the callbacks. See the \link flac_stream_encoder - * FLAC stream encoder module \endlink for full documentation. + * including the callbacks, with the addition of + * OggFLAC__stream_encoder_set_serial_number(). See the + * \link flac_stream_encoder FLAC stream encoder module \endlink + * for full documentation. * * \{ */ @@ -154,6 +157,17 @@ typedef struct { */ typedef FLAC__StreamEncoderWriteStatus (*OggFLAC__StreamEncoderWriteCallback)(const OggFLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data); +/** Signature for the metadata callback. + * See OggFLAC__stream_encoder_set_metadata_callback() + * and FLAC__stream_encoder_set_metadata_callback() for more info. + * + * \param encoder The encoder instance calling the callback. + * \param metadata The final populated STREAMINFO block. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_set_client_data(). + */ +typedef void (*OggFLAC__StreamEncoderMetadataCallback)(const OggFLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data); + /*********************************************************************** * @@ -439,6 +453,24 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_metadata(OggFLAC__StreamEncod */ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_write_callback(OggFLAC__StreamEncoder *encoder, OggFLAC__StreamEncoderWriteCallback value); +/** Set the metadata callback. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_metadata_callback(). + * + * \note + * The callback is mandatory and must be set before initialization. + * + * \default \c NULL + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \code value != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_metadata_callback(OggFLAC__StreamEncoder *encoder, OggFLAC__StreamEncoderMetadataCallback value); + /** Set the client data to be passed back to callbacks. * This value will be supplied to callbacks in their \a client_data * argument. diff --git a/src/libOggFLAC++/stream_encoder.cpp b/src/libOggFLAC++/stream_encoder.cpp index 52a0b1b..ab22170 100644 --- a/src/libOggFLAC++/stream_encoder.cpp +++ b/src/libOggFLAC++/stream_encoder.cpp @@ -296,6 +296,7 @@ namespace OggFLAC { { FLAC__ASSERT(is_valid()); ::OggFLAC__stream_encoder_set_write_callback(encoder_, write_callback_); + ::OggFLAC__stream_encoder_set_metadata_callback(encoder_, metadata_callback_); ::OggFLAC__stream_encoder_set_client_data(encoder_, (void*)this); return State(::OggFLAC__stream_encoder_init(encoder_)); } @@ -327,5 +328,14 @@ namespace OggFLAC { return instance->write_callback(buffer, bytes, samples, current_frame); } + void Stream::metadata_callback_(const ::OggFLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data) + { + (void)encoder; + FLAC__ASSERT(0 != client_data); + Stream *instance = reinterpret_cast(client_data); + FLAC__ASSERT(0 != instance); + return instance->metadata_callback(metadata); + } + }; }; diff --git a/src/libOggFLAC/stream_encoder.c b/src/libOggFLAC/stream_encoder.c index afcc5a9..98143d7 100644 --- a/src/libOggFLAC/stream_encoder.c +++ b/src/libOggFLAC/stream_encoder.c @@ -61,6 +61,7 @@ static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__S typedef struct OggFLAC__StreamEncoderPrivate { OggFLAC__StreamEncoderWriteCallback write_callback; + OggFLAC__StreamEncoderMetadataCallback metadata_callback; void *client_data; FLAC__StreamEncoder *FLAC_stream_encoder; /* internal vars (all the above are class settings) */ @@ -162,7 +163,7 @@ OggFLAC_API OggFLAC__StreamEncoderState OggFLAC__stream_encoder_init(OggFLAC__St if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED) return encoder->protected_->state = OggFLAC__STREAM_ENCODER_ALREADY_INITIALIZED; - if(0 == encoder->private_->write_callback) + if(0 == encoder->private_->write_callback || 0 == encoder->private_->metadata_callback) return encoder->protected_->state = OggFLAC__STREAM_ENCODER_INVALID_CALLBACK; if(ogg_stream_init(&encoder->private_->ogg.stream_state, encoder->protected_->serial_number) != 0) @@ -423,6 +424,18 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_write_callback(OggFLAC__Strea return true; } +OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_metadata_callback(OggFLAC__StreamEncoder *encoder, OggFLAC__StreamEncoderMetadataCallback value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != value); + if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->private_->metadata_callback = value; + return true; +} + OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_client_data(OggFLAC__StreamEncoder *encoder, void *value) { FLAC__ASSERT(0 != encoder); @@ -670,6 +683,7 @@ void set_defaults_(OggFLAC__StreamEncoder *encoder) FLAC__ASSERT(0 != encoder); encoder->private_->write_callback = 0; + encoder->private_->metadata_callback = 0; encoder->private_->client_data = 0; encoder->protected_->serial_number = 0; } @@ -717,13 +731,12 @@ FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *unused return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; } -void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data) +void metadata_callback_(const FLAC__StreamEncoder *unused, const FLAC__StreamMetadata *metadata, void *client_data) { - /* - * We don't try to go back and update metadata blocks by mucking - * around inside the Ogg layer. Maybe someday we will care to - * and an OggFLAC__SeekableStreamEncoder and OggFLAC__FileEncoder - * will be possible but it may just never be useful. - */ - (void)encoder, (void)metadata, (void)client_data; + OggFLAC__StreamEncoder *encoder = (OggFLAC__StreamEncoder*)client_data; + + (void)unused; + FLAC__ASSERT(encoder->private_->FLAC_stream_encoder == unused); + + encoder->private_->metadata_callback(encoder, metadata, encoder->private_->client_data); } diff --git a/src/test_libOggFLAC++/encoders.cpp b/src/test_libOggFLAC++/encoders.cpp index 1179226..0a30f71 100644 --- a/src/test_libOggFLAC++/encoders.cpp +++ b/src/test_libOggFLAC++/encoders.cpp @@ -48,6 +48,7 @@ public: // from OggFLAC::Encoder::Stream ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame); + void metadata_callback(const FLAC__StreamMetadata *metadata); bool die(const char *msg = 0) const; }; @@ -59,6 +60,11 @@ public: return ::FLAC__STREAM_ENCODER_WRITE_STATUS_OK; } +void StreamEncoder::metadata_callback(const FLAC__StreamMetadata *metadata) +{ + (void)metadata; +} + bool StreamEncoder::die(const char *msg) const { State state = get_state(); diff --git a/src/test_libOggFLAC/encoders.c b/src/test_libOggFLAC/encoders.c index 77bffe2..40c06fa 100644 --- a/src/test_libOggFLAC/encoders.c +++ b/src/test_libOggFLAC/encoders.c @@ -69,6 +69,12 @@ static FLAC__StreamEncoderWriteStatus stream_encoder_write_callback_(const OggFL return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; } +static void stream_encoder_metadata_callback_(const OggFLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data) +{ + (void)encoder, (void)metadata, (void)client_data; +} + + static FLAC__bool test_stream_encoder() { OggFLAC__StreamEncoder *encoder; @@ -191,6 +197,11 @@ static FLAC__bool test_stream_encoder() return die_s_("returned false", encoder); printf("OK\n"); + printf("testing OggFLAC__stream_encoder_set_metadata_callback()... "); + if(!OggFLAC__stream_encoder_set_metadata_callback(encoder, stream_encoder_metadata_callback_)) + return die_s_("returned false", encoder); + printf("OK\n"); + printf("testing OggFLAC__stream_encoder_set_client_data()... "); if(!OggFLAC__stream_encoder_set_client_data(encoder, 0)) return die_s_("returned false", encoder); -- 2.7.4