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 573a379..d73dac4 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 8f50e01..bbc128b 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 47d8665..a0adb05 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 75e2459..eb18622 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;
        }