temporary commit
authorJosh Coalson <jcoalson@users.sourceforce.net>
Wed, 21 Mar 2001 00:57:58 +0000 (00:57 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Wed, 21 Mar 2001 00:57:58 +0000 (00:57 +0000)
src/libFLAC/bitbuffer.c
src/libFLAC/encoder.c
src/libFLAC/encoder_framing.c

index 041b835..22bd908 100644 (file)
@@ -567,6 +567,67 @@ bool FLAC__bitbuffer_write_symmetric_rice_signed_guarded(FLAC__BitBuffer *bb, in
        return true;
 }
 
+static unsigned silog21_(int v)
+{
+doit_:
+       if(v == 0) {
+               return 0;
+       }
+       else if(v > 0) {
+               unsigned l = 0;
+               while(v) {
+                       l++;
+                       v >>= 1;
+               }
+               return l+1;
+       }
+       else if(v == -1) {
+               return 2;
+       }
+       else {
+               v = -(++v);
+               goto doit_;
+       }
+}
+
+bool FLAC__bitbuffer_write_symmetric_rice_signed_escape(FLAC__BitBuffer *bb, int val, unsigned parameter)
+{
+       unsigned total_bits, val_bits;
+       uint32 pattern;
+unsigned x;
+
+       assert(bb != 0);
+       assert(bb->buffer != 0);
+       assert(parameter <= 31);
+
+       val_bits = silog21_(val);
+       total_bits = 2 + parameter + 5 + val_bits;
+
+x=bb->total_bits;
+       if(total_bits <= 32) {
+               pattern = 3;
+               pattern <<= (parameter + 5);
+               pattern |= val_bits;
+               pattern <<= val_bits;
+               pattern |= (val & ((1 << val_bits) - 1));
+               if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, total_bits))
+                       return false;
+       }
+       else {
+               /* write the '-0' escape code first */
+               if(!FLAC__bitbuffer_write_raw_uint32(bb, 3u << parameter, 2+parameter))
+                       return false;
+               /* write the length */
+               if(!FLAC__bitbuffer_write_raw_uint32(bb, val_bits, 5))
+                       return false;
+               /* write the value */
+               if(!FLAC__bitbuffer_write_raw_int32(bb, val, val_bits))
+                       return false;
+       }
+fprintf(stderr,"wrote %u bits\n",bb->total_bits-x);
+       return true;
+}
+
 bool FLAC__bitbuffer_write_rice_signed(FLAC__BitBuffer *bb, int val, unsigned parameter)
 {
        unsigned total_bits, interesting_bits, msbs, uval;
index 533c31f..fbbd65a 100644 (file)
@@ -1054,19 +1054,45 @@ unsigned encoder_find_best_partition_order_(const int32 residual[], uint32 abs_r
        return best_residual_bits;
 }
 
-static unsigned iilog2_(unsigned v)
+static unsigned silog21_(int v)
+{
+doit_:
+       if(v == 0) {
+               return 0;
+       }
+       else if(v > 0) {
+               unsigned l = 0;
+               while(v) {
+                       l++;
+                       v >>= 1;
+               }
+               return l+1;
+       }
+       else if(v == -1) {
+               return 2;
+       }
+       else {
+               v = -(++v);
+               goto doit_;
+       }
+}
+
+static unsigned uilog21_(unsigned v)
 {
        unsigned l = 0;
-       assert(v > 0);
-       while(v >>= 1)
+       while(v) {
                l++;
+               v >>= 1;
+       }
        return l;
 }
 
+const double smult = 3.0;
+const unsigned rpdec = 0;
+
 static uint32 get_thresh_(const int32 residual[], const unsigned residual_samples)
 {
        double sum, sos, r, stddev, mean;
-       const double smult = 2.0;
        unsigned i;
        uint32 thresh;
 
@@ -1079,7 +1105,7 @@ static uint32 get_thresh_(const int32 residual[], const unsigned residual_sample
        mean = sum / residual_samples;
        stddev = sqrt((sos - (sum * sum / residual_samples)) / (residual_samples-1));
        thresh = mean+smult*stddev;
-       thresh = iilog2_(thresh);
+       thresh = (1u << uilog21_(thresh)) - 1;
        return thresh;
 }
 
@@ -1094,11 +1120,10 @@ bool encoder_set_partitioned_rice_(const int32 residual[], const uint32 abs_resi
 
        if(partition_order == 0) {
                unsigned i;
+#ifdef SYMMETRIC_RICE
                uint32 thresh = get_thresh_(residual, residual_samples);
-               const unsigned rpdec = 1;
                bool cross = false;
 
-#ifdef SYMMETRIC_RICE
                for(i=0;i<residual_samples;i++) {
                        if(abs_residual[i] >= thresh) {
                                cross = true;
@@ -1124,10 +1149,16 @@ bool encoder_set_partitioned_rice_(const int32 residual[], const uint32 abs_resi
                        for(i = 0; i < residual_samples; i++) {
 #ifdef VARIABLE_RICE_BITS
 #ifdef SYMMETRIC_RICE
-                               if(cross && abs_residual[i] >= thresh)
-                                       bits_ += VARIABLE_RICE_BITS(0, rice_parameter) + 5 + iilog2_(abs_residual) + 1;
-                               else
+                               if(cross) {
+                                       unsigned escbits, normbits;
+                                       escbits = /* VARIABLE_RICE_BITS(0, rice_parameter) == 0 */ 5 + silog21_(residual[i]);
+                                       normbits = VARIABLE_RICE_BITS(abs_residual[i], rice_parameter);
+                                       bits += min(escbits, normbits);
+                               }
+                               else {
+                                       /*@@@ old way */
                                        bits_ += VARIABLE_RICE_BITS(abs_residual[i], rice_parameter);
+                               }
 #else
                                bits_ += VARIABLE_RICE_BITS(abs_residual[i], rice_parameter_estimate);
 #endif
index 244b682..6a9eba3 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <assert.h>
 #include <stdio.h>
+#include <math.h>
 #include "private/encoder_framing.h"
 #include "private/crc.h"
 
@@ -319,16 +320,100 @@ bool subframe_add_entropy_coding_method_(FLAC__BitBuffer *bb, const FLAC__Entrop
        return true;
 }
 
+static unsigned silog21_(int v)
+{
+doit_:
+       if(v == 0) {
+               return 0;
+       }
+       else if(v > 0) {
+               unsigned l = 0;
+               while(v) {
+                       l++;
+                       v >>= 1;
+               }
+               return l+1;
+       }
+       else if(v == -1) {
+               return 2;
+       }
+       else {
+               v = -(++v);
+               goto doit_;
+       }
+}
+
+static unsigned uilog21_(unsigned v)
+{
+       unsigned l = 0;
+       while(v) {
+               l++;
+               v >>= 1;
+       }
+       return l;
+}
+
+extern const double smult;
+
+static uint32 get_thresh_(const int32 residual[], const unsigned residual_samples)
+{
+       double sum, sos, r, stddev, mean;
+       unsigned i;
+       uint32 thresh;
+
+       sum = sos = 0.0;
+       for(i = 0; i < residual_samples; i++) {
+               r = (double)residual[i];
+               sum += r;
+               sos += r*r;
+       }
+       mean = sum / residual_samples;
+       stddev = sqrt((sos - (sum * sum / residual_samples)) / (residual_samples-1));
+       thresh = mean+smult*stddev;
+       thresh = (1u << uilog21_(thresh)) - 1;
+       return thresh;
+}
+
 bool subframe_add_residual_partitioned_rice_(FLAC__BitBuffer *bb, const int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned partition_order)
 {
        if(partition_order == 0) {
                unsigned i;
+#ifdef SYMMETRIC_RICE
+               uint32 thresh = get_thresh_(residual, residual_samples);
+               bool cross = false;
+
+               for(i=0;i<residual_samples;i++) {
+                       uint32 a = (residual[i] < 0? -residual[i] : residual[i]);
+                       if(a >= thresh) {
+                               cross = true;
+                               break;
+                       }
+               }
+#endif
+
                if(!FLAC__bitbuffer_write_raw_uint32(bb, rice_parameters[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN))
                        return false;
                for(i = 0; i < residual_samples; i++) {
 #ifdef SYMMETRIC_RICE
-                       if(!FLAC__bitbuffer_write_symmetric_rice_signed(bb, residual[i], rice_parameters[0]))
-                               return false;
+                       if(cross) {
+                               unsigned escbits, normbits;
+                               uint32 a = (residual[i] < 0? -residual[i] : residual[i]);
+                               escbits = 5 + silog21_(residual[i]);
+                               normbits = a >> rice_parameters[0];
+                               if(escbits < normbits) {
+fprintf(stderr,"ESCAPE, k=%u, r=%d, saved %u bits\n", rice_parameters[0], residual[i], normbits-escbits);
+                                       if(!FLAC__bitbuffer_write_symmetric_rice_signed_escape(bb, residual[i], rice_parameters[0]))
+                                               return false;
+                               }
+                               else {
+                                       if(!FLAC__bitbuffer_write_symmetric_rice_signed(bb, residual[i], rice_parameters[0]))
+                                               return false;
+                               }
+                       }
+                       else {
+                               if(!FLAC__bitbuffer_write_symmetric_rice_signed(bb, residual[i], rice_parameters[0]))
+                                       return false;
+                       }
 #else
                        if(!FLAC__bitbuffer_write_rice_signed(bb, residual[i], rice_parameters[0]))
                                return false;