restrict subset to max blocksize of 16384 and max residual partition order of 8
authorJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 30 Aug 2002 05:47:14 +0000 (05:47 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 30 Aug 2002 05:47:14 +0000 (05:47 +0000)
doc/html/format.html
include/FLAC/stream_encoder.h
src/libFLAC/stream_encoder.c

index 5f10302..85223b8 100644 (file)
                        Individual subframes (one for each channel) are coded separately within a frame, and appear serially in the stream.  In other words, the encoded audio data is NOT channel-interleaved.  This reduces decoder complexity at the cost of requiring larger decode buffers.  Each subframe has its own header specifying the attributes of the subframe, like prediction method and order, residual coding parameters, etc.  The header is followed by the encoded audio data for that channel.
                </LI></P>
                <P><LI>
-                       <A NAME="subset">FLAC specifies a subset of itself as the Subset format.  The purpose of this is to ensure that any streams encoded according to the Subset are truly "streamable", meaning that a decoder that cannot seek within the stream can still pick up in the middle of the stream and start decoding.  It also makes hardware decoder implementations more practical by limiting the blocking such that decoder buffer sizes can be easily determined.  "flac" generates Subset streams by default unless the "--lax" command-line option is used.  The Subset makes the following limitations on what may be used in the stream:
+                       <A NAME="subset">FLAC specifies a subset of itself as the Subset format.  The purpose of this is to ensure that any streams encoded according to the Subset are truly "streamable", meaning that a decoder that cannot seek within the stream can still pick up in the middle of the stream and start decoding.  It also makes hardware decoder implementations more practical by limiting the encoding parameters such that decoder buffer sizes and other resource requirements can be easily determined.  "flac" generates Subset streams by default unless the "--lax" command-line option is used.  The Subset makes the following limitations on what may be used in the stream:
                        <UL>
                        <LI>
-                               The blocksize bits in the <A HREF="#frame_header">frame header</A> must be 0001-0101 or 1000-1111, specifying a fixed-blocksize stream (the exception being the last block as described in the table).  This also means that the STREAMINFO metadata block must specify equal mininum and maximum blocksizes.
+                               The blocksize bits in the <A HREF="#frame_header">frame header</A> must be 0001-0101 or 1000-1110, specifying a fixed-blocksize stream (the exception being the last block as described in the table) and a few allowable blocksizes.  This also means that the STREAMINFO metadata block must specify equal mininum and maximum blocksizes.
                        </LI>
                        <LI>
-                               The bits-per-sample bits in the <A HREF="#frame_header">frame header</A> must be 001-110.
+                               The sample rate bits in the <A HREF="#frame_header">frame header</A> must be 0001-1011.
                        </LI>
                        <LI>
-                               The sample rate bits in the <A HREF="#frame_header">frame header</A> must be 0001-1011.
+                               The bits-per-sample bits in the <A HREF="#frame_header">frame header</A> must be 001-111.
                        </LI>
                        </UL>
                </LI></P>
index a33530f..aa512af 100644 (file)
@@ -205,6 +205,9 @@ typedef enum {
        FLAC__STREAM_ENCODER_INVALID_BLOCK_SIZE,
        /**< The encoder has an invalid setting for the block size. */
 
+       FLAC__STREAM_ENCODER_INVALID_MAX_LPC_ORDER,
+       /**< The encoder has an invalid setting for the maximum LPC order. */
+
        FLAC__STREAM_ENCODER_INVALID_QLP_COEFF_PRECISION,
        /**< The encoder has an invalid setting for the precision of the quantized linear predictor coefficients. */
 
index 3eb43f5..f69e45b 100644 (file)
@@ -393,6 +393,7 @@ const char * const FLAC__StreamEncoderStateString[] = {
        "FLAC__STREAM_ENCODER_INVALID_BITS_PER_SAMPLE",
        "FLAC__STREAM_ENCODER_INVALID_SAMPLE_RATE",
        "FLAC__STREAM_ENCODER_INVALID_BLOCK_SIZE",
+       "FLAC__STREAM_ENCODER_INVALID_MAX_LPC_ORDER",
        "FLAC__STREAM_ENCODER_INVALID_QLP_COEFF_PRECISION",
        "FLAC__STREAM_ENCODER_MID_SIDE_CHANNELS_MISMATCH",
        "FLAC__STREAM_ENCODER_MID_SIDE_SAMPLE_SIZE_MISMATCH",
@@ -566,6 +567,9 @@ FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder *encoder)
        if(encoder->protected_->blocksize < FLAC__MIN_BLOCK_SIZE || encoder->protected_->blocksize > FLAC__MAX_BLOCK_SIZE)
                return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_BLOCK_SIZE;
 
+       if(encoder->protected_->max_lpc_order > FLAC__MAX_LPC_ORDER)
+               return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_MAX_LPC_ORDER;
+
        if(encoder->protected_->blocksize < encoder->protected_->max_lpc_order)
                return encoder->protected_->state = FLAC__STREAM_ENCODER_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER;
 
@@ -595,14 +599,45 @@ FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder *encoder)
                        encoder->protected_->qlp_coeff_precision = min(13, 8*sizeof(FLAC__int32) - encoder->protected_->bits_per_sample - 1 - 2); /* @@@ -2 to keep things 32-bit safe */
                }
        }
-       else if(encoder->protected_->qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION || encoder->protected_->qlp_coeff_precision + encoder->protected_->bits_per_sample >= 8*sizeof(FLAC__uint32) || encoder->protected_->qlp_coeff_precision >= (1u<<FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN))
+       else if(encoder->protected_->qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION || encoder->protected_->qlp_coeff_precision >= (1u<<FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN))
                return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_QLP_COEFF_PRECISION;
 
        if(encoder->protected_->streamable_subset) {
-               /*@@@ add check for blocksize here */
-               if(encoder->protected_->bits_per_sample != 8 && encoder->protected_->bits_per_sample != 12 && encoder->protected_->bits_per_sample != 16 && encoder->protected_->bits_per_sample != 20 && encoder->protected_->bits_per_sample != 24)
+               if(
+                       encoder->protected_->blocksize != 192 &&
+                       encoder->protected_->blocksize != 576 &&
+                       encoder->protected_->blocksize != 1152 &&
+                       encoder->protected_->blocksize != 2304 &&
+                       encoder->protected_->blocksize != 4608 &&
+                       encoder->protected_->blocksize != 256 &&
+                       encoder->protected_->blocksize != 512 &&
+                       encoder->protected_->blocksize != 1024 &&
+                       encoder->protected_->blocksize != 2048 &&
+                       encoder->protected_->blocksize != 4096 &&
+                       encoder->protected_->blocksize != 8192 &&
+                       encoder->protected_->blocksize != 16384
+               )
+                       return encoder->protected_->state = FLAC__STREAM_ENCODER_NOT_STREAMABLE;
+               if(
+                       encoder->protected_->sample_rate != 8000 &&
+                       encoder->protected_->sample_rate != 16000 &&
+                       encoder->protected_->sample_rate != 22050 &&
+                       encoder->protected_->sample_rate != 24000 &&
+                       encoder->protected_->sample_rate != 32000 &&
+                       encoder->protected_->sample_rate != 44100 &&
+                       encoder->protected_->sample_rate != 48000 &&
+                       encoder->protected_->sample_rate != 96000
+               )
+                       return encoder->protected_->state = FLAC__STREAM_ENCODER_NOT_STREAMABLE;
+               if(
+                       encoder->protected_->bits_per_sample != 8 &&
+                       encoder->protected_->bits_per_sample != 12 &&
+                       encoder->protected_->bits_per_sample != 16 &&
+                       encoder->protected_->bits_per_sample != 20 &&
+                       encoder->protected_->bits_per_sample != 24
+               )
                        return encoder->protected_->state = FLAC__STREAM_ENCODER_NOT_STREAMABLE;
-               if(encoder->protected_->sample_rate > 655350)
+               if(encoder->protected_->max_residual_partition_order > 8)
                        return encoder->protected_->state = FLAC__STREAM_ENCODER_NOT_STREAMABLE;
        }
 
@@ -2157,6 +2192,13 @@ unsigned evaluate_lpc_subframe_(
        int quantization, ret;
        const unsigned residual_samples = blocksize - order;
 
+       /* try to keep qlp coeff precision such that only 32-bit math is required for decode of <=16bps streams */
+       if(subframe_bps <= 16) {
+               FLAC__ASSERT(order > 0);
+               FLAC__ASSERT(order <= FLAC__MAX_LPC_ORDER);
+               qlp_coeff_precision = min(qlp_coeff_precision, 32 - subframe_bps - FLAC__bitmath_ilog2(order));
+       }
+
        ret = FLAC__lpc_quantize_coefficients(lp_coeff, order, qlp_coeff_precision, subframe_bps, qlp_coeff, &quantization);
        if(ret != 0)
                return 0; /* this is a hack to indicate to the caller that we can't do lp at this order on this subframe */
@@ -2345,7 +2387,7 @@ unsigned find_best_partition_order_(
        }
 
        /*
-        * We are allowed to de-const the pointer based on our special knowledhe;
+        * We are allowed to de-const the pointer based on our special knowledge;
         * it is const to the outside world.
         */
        {