From 4598b1c8b00d4870028060166b70743ec779e148 Mon Sep 17 00:00:00 2001 From: Josh Coalson Date: Fri, 3 Sep 2004 01:03:23 +0000 Subject: [PATCH] "finalize" Ogg FLAC mapping version 1.0 by prepending "FLAC" magic and a 2 byte mapping version number to the first packet --- .../include/private/ogg_decoder_aspect.h | 3 ++ src/libOggFLAC/ogg_decoder_aspect.c | 18 +++++++++ src/libOggFLAC/ogg_encoder_aspect.c | 44 +++++++++++++++++----- src/libOggFLAC/stream_decoder.c | 2 + 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/src/libOggFLAC/include/private/ogg_decoder_aspect.h b/src/libOggFLAC/include/private/ogg_decoder_aspect.h index c387109..77e02e9 100644 --- a/src/libOggFLAC/include/private/ogg_decoder_aspect.h +++ b/src/libOggFLAC/include/private/ogg_decoder_aspect.h @@ -45,6 +45,7 @@ typedef struct OggFLAC__OggDecoderAspect { /* these are for internal state related to Ogg decoding */ ogg_stream_state stream_state; ogg_sync_state sync_state; + unsigned version_major, version_minor; FLAC__bool need_serial_number; FLAC__bool end_of_stream; FLAC__bool have_working_page; /* only if true will the following vars be valid */ @@ -64,6 +65,8 @@ typedef enum { OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_OK = 0, OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM, OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC, + OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC, + OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION, OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT, OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR, OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR diff --git a/src/libOggFLAC/ogg_decoder_aspect.c b/src/libOggFLAC/ogg_decoder_aspect.c index a0f34a6..0627478 100644 --- a/src/libOggFLAC/ogg_decoder_aspect.c +++ b/src/libOggFLAC/ogg_decoder_aspect.c @@ -32,6 +32,7 @@ #include /* for memcpy() */ #include "FLAC/assert.h" #include "private/ogg_decoder_aspect.h" +#include "private/ogg_mapping.h" #ifdef max #undef max @@ -53,6 +54,9 @@ FLAC__bool OggFLAC__ogg_decoder_aspect_init(OggFLAC__OggDecoderAspect *aspect) if(ogg_sync_init(&aspect->sync_state) != 0) return false; + aspect->version_major = ~(0u); + aspect->version_minor = ~(0u); + aspect->need_serial_number = aspect->use_first_serial_number; aspect->end_of_stream = false; @@ -149,6 +153,20 @@ OggFLAC__OggDecoderAspectReadStatus OggFLAC__ogg_decoder_aspect_read_callback_wr const int ret = ogg_stream_packetout(&aspect->stream_state, &aspect->working_packet); if (ret > 0) { aspect->have_working_packet = true; + /* if it is packet 0, check for magic and a supported Ogg FLAC mapping version */ + if (aspect->working_packet.packetno == 0) { + const unsigned header_length = OggFLAC__MAPPING_MAGIC_LENGTH + OggFLAC__MAPPING_VERSION_MAJOR_LENGTH + OggFLAC__MAPPING_VERSION_MINOR_LENGTH; + if (aspect->working_packet.bytes < (long)header_length) + return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC; + if (memcmp(aspect->working_packet.packet, OggFLAC__MAPPING_MAGIC, OggFLAC__MAPPING_MAGIC_LENGTH)) + return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC; + aspect->version_major = (unsigned)aspect->working_packet.packet[OggFLAC__MAPPING_MAGIC_LENGTH]; + aspect->version_minor = (unsigned)aspect->working_packet.packet[OggFLAC__MAPPING_MAGIC_LENGTH+OggFLAC__MAPPING_VERSION_MAJOR_LENGTH]; + if (aspect->version_major != 1) + return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION; + aspect->working_packet.packet += header_length; + aspect->working_packet.bytes -= header_length; + } } else if (ret == 0) { aspect->have_working_page = false; diff --git a/src/libOggFLAC/ogg_encoder_aspect.c b/src/libOggFLAC/ogg_encoder_aspect.c index 38efc1e..9c9ef7d 100644 --- a/src/libOggFLAC/ogg_encoder_aspect.c +++ b/src/libOggFLAC/ogg_encoder_aspect.c @@ -32,6 +32,10 @@ #include /* for memset() */ #include "FLAC/assert.h" #include "private/ogg_encoder_aspect.h" +#include "private/ogg_mapping.h" + +static const FLAC__byte OggFLAC__MAPPING_VERSION_MAJOR = 1; +static const FLAC__byte OggFLAC__MAPPING_VERSION_MINOR = 0; /*********************************************************************** * @@ -72,13 +76,14 @@ void OggFLAC__ogg_encoder_aspect_set_defaults(OggFLAC__OggEncoderAspect *aspect) * The basic FLAC -> Ogg mapping goes like this: * * - 'fLaC' magic and STREAMINFO block get combined into the first - * packet - * - the first packet is flushed to the first page - * - each subsequent metadata block goes into its own packet - * - each metadata packet is flushed to page (this is not required, + * packet. The packet is prefixed with 'FLAC' magic and the 2 + * byte Ogg FLAC mapping version number. + * - The first packet is flushed to the first page. + * - Each subsequent metadata block goes into its own packet. + * - Each metadata packet is flushed to page (this is not required, * the mapping only requires that a flush must occur after all - * metadata is written) - * - each subsequent FLAC audio frame goes into its own packet. + * metadata is written). + * - Each subsequent FLAC audio frame goes into its own packet. * * WATCHOUT: * This depends on the behavior of FLAC__StreamEncoder that we get a @@ -104,7 +109,15 @@ FLAC__StreamEncoderWriteStatus OggFLAC__ogg_encoder_aspect_write_callback_wrappe packet.granulepos = aspect->samples_written + samples; if(aspect->is_first_packet) { - FLAC__byte newbuffer[FLAC__STREAM_SYNC_LENGTH + FLAC__STREAM_METADATA_HEADER_LENGTH + FLAC__STREAM_METADATA_STREAMINFO_LENGTH]; + FLAC__byte newbuffer[ + OggFLAC__MAPPING_MAGIC_LENGTH + + OggFLAC__MAPPING_VERSION_MAJOR_LENGTH + + OggFLAC__MAPPING_VERSION_MINOR_LENGTH + + FLAC__STREAM_SYNC_LENGTH + + FLAC__STREAM_METADATA_HEADER_LENGTH + + FLAC__STREAM_METADATA_STREAMINFO_LENGTH + ]; + FLAC__byte *b = newbuffer; if(bytes != FLAC__STREAM_METADATA_HEADER_LENGTH + FLAC__STREAM_METADATA_STREAMINFO_LENGTH) { /* * If we get here, our assumption about the way write callbacks happen @@ -113,8 +126,21 @@ FLAC__StreamEncoderWriteStatus OggFLAC__ogg_encoder_aspect_write_callback_wrappe FLAC__ASSERT(0); return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; } - memcpy(newbuffer, FLAC__STREAM_SYNC_STRING, FLAC__STREAM_SYNC_LENGTH); - memcpy(newbuffer + FLAC__STREAM_SYNC_LENGTH, buffer, bytes); + /* add 'FLAC' mapping magic */ + memcpy(b, OggFLAC__MAPPING_MAGIC, OggFLAC__MAPPING_MAGIC_LENGTH); + b += OggFLAC__MAPPING_MAGIC_LENGTH; + /* add Ogg FLAC mapping major version number */ + memcpy(b, &OggFLAC__MAPPING_VERSION_MAJOR, OggFLAC__MAPPING_VERSION_MAJOR_LENGTH); + b += OggFLAC__MAPPING_VERSION_MAJOR_LENGTH; + /* add Ogg FLAC mapping minor version number */ + memcpy(b, &OggFLAC__MAPPING_VERSION_MINOR, OggFLAC__MAPPING_VERSION_MINOR_LENGTH); + b += OggFLAC__MAPPING_VERSION_MINOR_LENGTH; + /* add native FLAC 'fLaC' magic */ + memcpy(b, FLAC__STREAM_SYNC_STRING, FLAC__STREAM_SYNC_LENGTH); + b += FLAC__STREAM_SYNC_LENGTH; + /* add STREAMINFO */ + memcpy(b, buffer, bytes); + FLAC__ASSERT(b + bytes - newbuffer == sizeof(newbuffer)); packet.packet = (unsigned char *)newbuffer; packet.bytes = sizeof(newbuffer); diff --git a/src/libOggFLAC/stream_decoder.c b/src/libOggFLAC/stream_decoder.c index 73f56ef..be7c5d6 100644 --- a/src/libOggFLAC/stream_decoder.c +++ b/src/libOggFLAC/stream_decoder.c @@ -506,6 +506,8 @@ FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *unused, return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM: return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC: + case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION: case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT: case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR: decoder->protected_->state = OggFLAC__STREAM_DECODER_READ_ERROR; -- 2.7.4