add md5.o
[flac.git] / src / libFLAC / encoder.c
index 2a6fffa..dccf796 100644 (file)
@@ -26,6 +26,7 @@
 #include "private/encoder_framing.h"
 #include "private/fixed.h"
 #include "private/lpc.h"
+#include "private/md5.h"
 
 #ifdef min
 #undef min
 #endif
 #define max(x,y) ((x)>(y)?(x):(y))
 
-#ifdef RICE_BITS
-#undef RICE_BITS
-#endif
-#define RICE_BITS(value, parameter) (2 + (parameter) + (((unsigned)((value) < 0? -(value) : (value))) >> (parameter)))
-
 typedef struct FLAC__EncoderPrivate {
        unsigned input_capacity;                    /* current size (in samples) of the signal and residual buffers */
        int32 *integer_signal[FLAC__MAX_CHANNELS];  /* the integer version of the input signal */
@@ -59,6 +55,7 @@ typedef struct FLAC__EncoderPrivate {
        FLAC__StreamMetaData metadata;
        unsigned current_sample_number;
        unsigned current_frame_number;
+       struct MD5Context md5context;
        FLAC__EncoderWriteStatus (*write_callback)(const FLAC__Encoder *encoder, const byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
        void (*metadata_callback)(const FLAC__Encoder *encoder, const FLAC__StreamMetaData *metadata, void *client_data);
        void *client_data;
@@ -79,6 +76,29 @@ static bool encoder_generate_verbatim_subframe_(const FLAC__SubframeHeader *head
 static void encoder_promote_candidate_subframe_(FLAC__Encoder *encoder);
 static bool encoder_set_partitioned_rice_(const int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameter, const unsigned partition_order, unsigned parameters[], unsigned *bits);
 
+const char *FLAC__EncoderWriteStatusString[] = {
+       "FLAC__ENCODER_WRITE_OK",
+       "FLAC__ENCODER_WRITE_FATAL_ERROR"
+};
+
+const char *FLAC__EncoderStateString[] = {
+       "FLAC__ENCODER_OK",
+       "FLAC__ENCODER_UNINITIALIZED",
+       "FLAC__ENCODER_INVALID_NUMBER_OF_CHANNELS",
+       "FLAC__ENCODER_INVALID_BITS_PER_SAMPLE",
+       "FLAC__ENCODER_INVALID_SAMPLE_RATE",
+       "FLAC__ENCODER_INVALID_BLOCK_SIZE",
+       "FLAC__ENCODER_INVALID_QLP_COEFF_PRECISION",
+       "FLAC__ENCODER_MID_SIDE_CHANNELS_MISMATCH",
+       "FLAC__ENCODER_MID_SIDE_SAMPLE_SIZE_MISMATCH",
+       "FLAC__ENCODER_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER",
+       "FLAC__ENCODER_NOT_STREAMABLE",
+       "FLAC__ENCODER_FRAMING_ERROR",
+       "FLAC__ENCODER_FATAL_ERROR_WHILE_ENCODING",
+       "FLAC__ENCODER_FATAL_ERROR_WHILE_WRITING",
+       "FLAC__ENCODER_MEMORY_ALLOCATION_ERROR"
+};
+
 
 bool encoder_resize_buffers_(FLAC__Encoder *encoder, unsigned new_size)
 {
@@ -311,6 +331,8 @@ FLAC__EncoderState FLAC__encoder_init(FLAC__Encoder *encoder, FLAC__EncoderWrite
        encoder->guts->metadata.data.encoding.channels = encoder->channels;
        encoder->guts->metadata.data.encoding.bits_per_sample = encoder->bits_per_sample;
        encoder->guts->metadata.data.encoding.total_samples = 0; /* we don't know this yet; have to fill it in later */
+       memset(encoder->guts->metadata.data.encoding.md5sum, 0, 16); /* we don't know this yet; have to fill it in later */
+       MD5Init(&encoder->guts->md5context);
        if(!FLAC__add_metadata_block(&encoder->guts->metadata, &encoder->guts->frame))
                return encoder->state = FLAC__ENCODER_FRAMING_ERROR;
 
@@ -336,6 +358,7 @@ void FLAC__encoder_finish(FLAC__Encoder *encoder)
                encoder->blocksize = encoder->guts->current_sample_number;
                encoder_process_frame_(encoder, true); /* true => is last frame */
        }
+       MD5Final(encoder->guts->metadata.data.encoding.md5sum, &encoder->guts->md5context);
        encoder->guts->metadata_callback(encoder, &encoder->guts->metadata, encoder->guts->client_data);
        if(encoder->guts != 0) {
                for(i = 0; i < encoder->channels; i++) {
@@ -471,6 +494,14 @@ bool encoder_process_frame_(FLAC__Encoder *encoder, bool is_last_frame)
        assert(encoder->state == FLAC__ENCODER_OK);
 
        /*
+        * Accumulate raw signal to the MD5 signature
+        */
+       if(!FLAC__MD5Accumulate(&encoder->guts->md5context, encoder->guts->integer_signal, encoder->channels, encoder->blocksize, (encoder->bits_per_sample+7) / 8)) {
+               encoder->state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR;
+               return false;
+       }
+
+       /*
         * First do a normal encoding pass
         */
        frame_header.blocksize = encoder->blocksize;
@@ -627,10 +658,20 @@ bool encoder_process_subframes_(FLAC__Encoder *encoder, bool is_last_frame, cons
                        /* check for constant subframe */
                        guess_fixed_order = FLAC__fixed_compute_best_predictor(integer_signal[channel]+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample);
                        if(fixed_residual_bits_per_sample[1] == 0.0) {
-                               candidate_bits = encoder_evaluate_constant_subframe_(integer_signal[channel][0], frame_header->bits_per_sample, &(encoder->guts->candidate_subframe));
-                               if(candidate_bits < best_bits) {
-                                       encoder_promote_candidate_subframe_(encoder);
-                                       best_bits = candidate_bits;
+                               /* the above means integer_signal[channel]+FLAC__MAX_FIXED_ORDER is constant, now we just have to check the warmup samples */
+                               unsigned i, signal_is_constant = true;
+                               for(i = 1; i <= FLAC__MAX_FIXED_ORDER; i++) {
+                                       if(integer_signal[channel][0] != integer_signal[channel][i]) {
+                                               signal_is_constant = false;
+                                               break;
+                                       }
+                               }
+                               if(signal_is_constant) {
+                                       candidate_bits = encoder_evaluate_constant_subframe_(integer_signal[channel][0], frame_header->bits_per_sample, &(encoder->guts->candidate_subframe));
+                                       if(candidate_bits < best_bits) {
+                                               encoder_promote_candidate_subframe_(encoder);
+                                               best_bits = candidate_bits;
+                                       }
                                }
                        }
                        else {
@@ -645,7 +686,8 @@ bool encoder_process_subframes_(FLAC__Encoder *encoder, bool is_last_frame, cons
                                for(fixed_order = min_fixed_order; fixed_order <= max_fixed_order; fixed_order++) {
                                        if(fixed_residual_bits_per_sample[fixed_order] >= (real)frame_header->bits_per_sample)
                                                continue; /* don't even try */
-                                       rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > 0.0)? (unsigned)(fixed_residual_bits_per_sample[fixed_order]+0.5) : 0;
+                                       /* 0.5 is for rounding, another 1.0 is to account for the signed->unsigned conversion during rice coding */
+                                       rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > 0.0)? (unsigned)(fixed_residual_bits_per_sample[fixed_order]+1.5) : 0;
                                        if(rice_parameter >= (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN))
                                                rice_parameter = (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN) - 1;
                                        candidate_bits = encoder_evaluate_fixed_subframe_(integer_signal[channel], encoder->guts->residual[!encoder->guts->best_residual], frame_header->blocksize, frame_header->bits_per_sample, fixed_order, rice_parameter, max_partition_order, &(encoder->guts->candidate_subframe));
@@ -682,7 +724,8 @@ bool encoder_process_subframes_(FLAC__Encoder *encoder, bool is_last_frame, cons
                                                        lpc_residual_bits_per_sample = FLAC__lpc_compute_expected_bits_per_residual_sample(lpc_error[lpc_order-1], frame_header->blocksize);
                                                        if(lpc_residual_bits_per_sample >= (real)frame_header->bits_per_sample)
                                                                continue; /* don't even try */
-                                                       rice_parameter = (lpc_residual_bits_per_sample > 0.0)? (unsigned)(lpc_residual_bits_per_sample+0.5) : 0;
+                                                       /* 0.5 is for rounding, another 1.0 is to account for the signed->unsigned conversion during rice coding */
+                                                       rice_parameter = (lpc_residual_bits_per_sample > 0.0)? (unsigned)(lpc_residual_bits_per_sample+1.5) : 0;
                                                        if(rice_parameter >= (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN))
                                                                rice_parameter = (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN) - 1;
                                                        for(qlp_coeff_precision = min_qlp_coeff_precision; qlp_coeff_precision <= max_qlp_coeff_precision; qlp_coeff_precision++) {
@@ -737,7 +780,7 @@ unsigned encoder_evaluate_constant_subframe_(const int32 signal, unsigned bits_p
        subframe->type = FLAC__SUBFRAME_TYPE_CONSTANT;
        subframe->data.constant.value = signal;
 
-       return 8 + bits_per_sample;
+       return FLAC__SUBFRAME_HEADER_TYPE_LEN + bits_per_sample;
 }
 
 unsigned encoder_evaluate_fixed_subframe_(const int32 signal[], int32 residual[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned rice_parameter, unsigned max_partition_order, FLAC__SubframeHeader *subframe)
@@ -757,7 +800,7 @@ unsigned encoder_evaluate_fixed_subframe_(const int32 signal[], int32 residual[]
        for(i = 0; i < order; i++)
                subframe->data.fixed.warmup[i] = signal[i];
 
-       return 8 + (order * bits_per_sample) + residual_bits;
+       return FLAC__SUBFRAME_HEADER_TYPE_LEN + (order * bits_per_sample) + residual_bits;
 }
 
 unsigned encoder_evaluate_lpc_subframe_(const int32 signal[], int32 residual[], const real lp_coeff[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, unsigned max_partition_order, FLAC__SubframeHeader *subframe)
@@ -786,14 +829,14 @@ unsigned encoder_evaluate_lpc_subframe_(const int32 signal[], int32 residual[],
        for(i = 0; i < order; i++)
                subframe->data.lpc.warmup[i] = signal[i];
 
-       return 8 + 9 + (order * (qlp_coeff_precision + bits_per_sample)) + residual_bits;
+       return FLAC__SUBFRAME_HEADER_TYPE_LEN + FLAC__SUBFRAME_HEADER_LPC_QLP_COEFF_PRECISION_LEN + FLAC__SUBFRAME_HEADER_LPC_QLP_SHIFT_LEN + (order * (qlp_coeff_precision + bits_per_sample)) + residual_bits;
 }
 
 unsigned encoder_evaluate_verbatim_subframe_(unsigned blocksize, unsigned bits_per_sample, FLAC__SubframeHeader *subframe)
 {
        subframe->type = FLAC__SUBFRAME_TYPE_VERBATIM;
 
-       return 8 + (blocksize * bits_per_sample);
+       return FLAC__SUBFRAME_HEADER_TYPE_LEN + (blocksize * bits_per_sample);
 }
 
 unsigned encoder_find_best_partition_order_(int32 residual[], unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, unsigned max_partition_order, unsigned *best_partition_order, unsigned best_parameters[])
@@ -854,19 +897,18 @@ void encoder_promote_candidate_subframe_(FLAC__Encoder *encoder)
 
 bool encoder_set_partitioned_rice_(const int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameter, const unsigned partition_order, unsigned parameters[], unsigned *bits)
 {
-       unsigned bits_ = 2 + 3;
+       unsigned bits_ = FLAC__ENTROPY_CODING_METHOD_TYPE_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN;
 
        if(partition_order == 0) {
                unsigned i;
                parameters[0] = rice_parameter;
                bits_ += FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
                for(i = 0; i < residual_samples; i++)
-                       bits_ += RICE_BITS(residual[i], rice_parameter);
+                       bits_ += FLAC__bitbuffer_rice_bits(residual[i], rice_parameter);
        }
        else {
-               unsigned i, j, k = 0, k_last = 0, z;
-               unsigned mean;
-               unsigned parameter, partition_samples;
+               unsigned i, j, k = 0, k_last = 0;
+               unsigned mean, parameter, partition_samples;
                const unsigned max_parameter = (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN) - 1;
                for(i = 0; i < (1u<<partition_order); i++) {
                        partition_samples = (residual_samples+predictor_order) >> partition_order;
@@ -880,17 +922,18 @@ bool encoder_set_partitioned_rice_(const int32 residual[], const unsigned residu
                        for(j = 0; j < partition_samples; j++, k++)
                                mean += ((residual[k] < 0)? (unsigned)(-residual[k]) : (unsigned)residual[k]);
                        mean /= partition_samples;
-                       z = 0x80000000;
-                       for(j = 0; j < 32; j++, z >>= 1)
-                               if(mean & z)
-                                       break;
-                       parameter = j > 31? 0 : 32 - j - 1;
+                       /* calc parameter = floor(log2(mean)) + 1 */
+                       parameter = 0;
+                       while(mean) {
+                               parameter++;
+                               mean >>= 1;
+                       }
                        if(parameter > max_parameter)
                                parameter = max_parameter;
                        parameters[i] = parameter;
                        bits_ += FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
                        for(j = k_last; j < k; j++)
-                               bits_ += RICE_BITS(residual[j], parameter);
+                               bits_ += FLAC__bitbuffer_rice_bits(residual[j], parameter);
                        k_last = k;
                }
        }