add support for last_metadata_is_last flag in the stream encoder
authorJosh Coalson <jcoalson@users.sourceforce.net>
Thu, 14 Jun 2001 19:09:02 +0000 (19:09 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Thu, 14 Jun 2001 19:09:02 +0000 (19:09 +0000)
doc/documentation.html
include/FLAC/stream_encoder.h
src/flac/encode.c
src/libFLAC/stream_encoder.c

index 573a37924c4279d7940ce72ef19122611cadcb03..d73dac48d0d72c07a0986b0824ef49f15b0a41c5 100644 (file)
                        <LI><B><TT>total_samples_estimate</TT></B> - May be set to 0 if unknown.  Otherwise, set this to the number of samples to be encoded.  This will allow the STREAMINFO block to be more accurate during the first pass in the event that the encoder can't seek back to the beginning of the output file to write the updated STREAMINFO block.</LI>
                        <LI><B><TT>seek_table</TT></B> - Optional seek table to prepend; NULL implies no seek table.</LI>
                        <LI><B><TT>padding</TT></B> - Size of PADDING block to add (goes after seek table); 0 implies do not add a PADDING block.</LI>
+                       <LI><B><TT>last_metadata_is_last</TT></B> - The value the encoder will use for the 'is_last' flag of the last metadata block it writes.  In normal usage you would set this to true, but if you will be manually inserting more metadata blocks between the time of the first write callback (when the encoder sends the <TT>fLaC</TT> header and metadata) and the time actual audio encoding starts then set this to false.</LI>
                </UL>
        </P>
        <P>
index 8f50e01e4adec76398383fadf96a45e662666838..bbc128be973f84f521c777db7ef49088582884b0 100644 (file)
@@ -103,6 +103,8 @@ FLAC__StreamEncoderState FLAC__stream_encoder_init(
        uint64   total_samples_estimate,      /* may be 0 if unknown.  this will be a placeholder in the metadata block until the actual total is calculated */
        const FLAC__StreamMetaData_SeekTable *seek_table, /* optional seek_table to prepend, 0 => no seek table */
        unsigned padding,                     /* size of PADDING block to add (goes after seek table); 0 => do not add a PADDING block */
+       bool     last_metadata_is_last,       /* the value the encoder will use for the 'is_last' flag of the last metadata block it writes; set this to false */
+                                             /* if you will be adding more metadata blocks before the audio frames, else true */
        FLAC__StreamEncoderWriteStatus (*write_callback)(const FLAC__StreamEncoder *encoder, const byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data),
        void (*metadata_callback)(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetaData *metadata, void *client_data),
        void *client_data
index 47d8665eb75ce0fef68a89490c42e83f420afdef..a0adb050ab527ab856882c3a45cba3ffd1f87295 100644 (file)
@@ -155,11 +155,11 @@ int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, cons
                                fprintf(stderr, "WARNING: skipping extra 'fmt ' sub-chunk\n");
                        }
                        else {
-                               /* fmt chunk size */
+                               /* fmt sub-chunk size */
                                if(!read_little_endian_uint32(infile, &xx, false))
                                        goto wav_abort_;
                                if(xx != 16) {
-                                       fprintf(stderr, "ERROR: unsupported chunk\n");
+                                       fprintf(stderr, "ERROR: unsupported non-standard 'fmt ' sub-chunk has length %u != 16\n", (unsigned)xx);
                                        goto wav_abort_;
                                }
                                /* compression code */
@@ -260,7 +260,7 @@ int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, cons
                                        }
                                        else {
                                                if(bytes_read > data_bytes)
-                                                       bytes_read = data_bytes; /* chop off anything after the end of the data chunk */
+                                                       bytes_read = data_bytes; /* chop off anything after the end of the data sub-chunk */
                                                if(bytes_read % bytes_per_wide_sample != 0) {
                                                        fprintf(stderr, "ERROR, got partial sample from input file %s\n", infilename);
                                                        goto wav_abort_;
@@ -283,7 +283,7 @@ int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, cons
                }
                else {
                        fprintf(stderr, "WARNING: skipping unknown sub-chunk '%c%c%c%c'\n", (char)(xx&255), (char)((xx>>8)&255), (char)((xx>>16)&255), (char)(xx>>24));
-                       /* chunk size */
+                       /* sub-chunk size */
                        if(!read_little_endian_uint32(infile, &xx, false))
                                goto wav_abort_;
                        if(infile != stdin) {
@@ -583,7 +583,7 @@ bool init_encoder(bool lax, bool do_mid_side, bool loose_mid_side, bool do_exhau
                return false;
        }
 
-       if(FLAC__stream_encoder_init(encoder_wrapper->encoder, !lax, do_mid_side, loose_mid_side, channels, bps, sample_rate, blocksize, max_lpc_order, qlp_coeff_precision, do_qlp_coeff_prec_search, do_exhaustive_model_search, min_residual_partition_order, max_residual_partition_order, rice_parameter_search_dist, encoder_wrapper->total_samples_to_encode, (encoder_wrapper->seek_table.num_points > 0)? &encoder_wrapper->seek_table : 0, padding, write_callback, metadata_callback, encoder_wrapper) != FLAC__STREAM_ENCODER_OK) {
+       if(FLAC__stream_encoder_init(encoder_wrapper->encoder, !lax, do_mid_side, loose_mid_side, channels, bps, sample_rate, blocksize, max_lpc_order, qlp_coeff_precision, do_qlp_coeff_prec_search, do_exhaustive_model_search, min_residual_partition_order, max_residual_partition_order, rice_parameter_search_dist, encoder_wrapper->total_samples_to_encode, (encoder_wrapper->seek_table.num_points > 0)? &encoder_wrapper->seek_table : 0, padding, true /*last_metadata_is_last*/, write_callback, metadata_callback, encoder_wrapper) != FLAC__STREAM_ENCODER_OK) {
                fprintf(stderr, "ERROR initializing encoder, state = %d:%s\n", FLAC__stream_encoder_state(encoder_wrapper->encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_state(encoder_wrapper->encoder)]);
                return false;
        }
index 75e2459114debf54888a3e65fc1b927c4b9c1869..eb1862270536e51004eb1b52a068553524dd5b2a 100644 (file)
@@ -221,6 +221,7 @@ FLAC__StreamEncoderState FLAC__stream_encoder_init(
        uint64 total_samples_estimate,
        const FLAC__StreamMetaData_SeekTable *seek_table,
        unsigned padding,
+       bool last_metadata_is_last,
        FLAC__StreamEncoderWriteStatus (*write_callback)(const FLAC__StreamEncoder *encoder, const byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data),
        void (*metadata_callback)(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetaData *metadata, void *client_data),
        void *client_data)
@@ -254,7 +255,6 @@ FLAC__StreamEncoderState FLAC__stream_encoder_init(
        encoder->protected->rice_parameter_search_dist = rice_parameter_search_dist;
        encoder->protected->total_samples_estimate = total_samples_estimate;
        encoder->protected->seek_table = seek_table;
-       encoder->protected->padding = padding;
 
        if(encoder->protected->channels == 0 || encoder->protected->channels > FLAC__MAX_CHANNELS)
                return encoder->protected->state = FLAC__STREAM_ENCODER_INVALID_NUMBER_OF_CHANNELS;
@@ -425,7 +425,7 @@ FLAC__StreamEncoderState FLAC__stream_encoder_init(
                return encoder->protected->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
 
        encoder->private->metadata.type = FLAC__METADATA_TYPE_STREAMINFO;
-       encoder->private->metadata.is_last = (encoder->protected->seek_table == 0 && encoder->protected->padding == 0);
+       encoder->private->metadata.is_last = (encoder->protected->seek_table == 0 && padding == 0 && last_metadata_is_last);
        encoder->private->metadata.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
        encoder->private->metadata.data.stream_info.min_blocksize = encoder->protected->blocksize; /* this encoder uses the same blocksize for the whole stream */
        encoder->private->metadata.data.stream_info.max_blocksize = encoder->protected->blocksize;
@@ -444,7 +444,7 @@ FLAC__StreamEncoderState FLAC__stream_encoder_init(
                if(!FLAC__seek_table_is_valid(encoder->protected->seek_table))
                        return encoder->protected->state = FLAC__STREAM_ENCODER_INVALID_SEEK_TABLE;
                seek_table_block.type = FLAC__METADATA_TYPE_SEEKTABLE;
-               seek_table_block.is_last = (encoder->protected->padding == 0);
+               seek_table_block.is_last = (padding == 0 && last_metadata_is_last);
                seek_table_block.length = encoder->protected->seek_table->num_points * FLAC__STREAM_METADATA_SEEKPOINT_LEN;
                seek_table_block.data.seek_table = *encoder->protected->seek_table;
                if(!FLAC__add_metadata_block(&seek_table_block, &encoder->private->frame))
@@ -452,10 +452,10 @@ FLAC__StreamEncoderState FLAC__stream_encoder_init(
        }
 
        /* add a PADDING block if requested */
-       if(encoder->protected->padding > 0) {
+       if(padding > 0) {
                padding_block.type = FLAC__METADATA_TYPE_PADDING;
-               padding_block.is_last = true;
-               padding_block.length = encoder->protected->padding;
+               padding_block.is_last = last_metadata_is_last;
+               padding_block.length = padding;
                if(!FLAC__add_metadata_block(&padding_block, &encoder->private->frame))
                        return encoder->protected->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
        }