From 05f710f4e02a95defc26b38edfaa5c5c2dbef416 Mon Sep 17 00:00:00 2001 From: Josh Coalson Date: Tue, 31 Jul 2007 00:51:26 +0000 Subject: [PATCH] add support for RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 and blocking strategy bit --- src/libFLAC/format.c | 4 +- src/libFLAC/stream_encoder.c | 108 ++++++++++++++++++--------- src/libFLAC/stream_encoder_framing.c | 85 ++++++++++++++------- 3 files changed, 135 insertions(+), 62 deletions(-) diff --git a/src/libFLAC/format.c b/src/libFLAC/format.c index 07d45747..b3de576c 100644 --- a/src/libFLAC/format.c +++ b/src/libFLAC/format.c @@ -61,9 +61,9 @@ FLAC_API const char *FLAC__VERSION_STRING = VERSION; #if defined _MSC_VER || defined __BORLANDC__ || defined __MINW32__ /* yet one more hack because of MSVC6: */ -FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.2.0 20070715"; +FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.2.0 CVS-20070730"; #else -FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20070715"; +FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " CVS-20070730"; #endif FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c index 1a805458..85109cfd 100644 --- a/src/libFLAC/stream_encoder.c +++ b/src/libFLAC/stream_encoder.c @@ -198,6 +198,7 @@ static unsigned evaluate_fixed_subframe_( unsigned subframe_bps, unsigned order, unsigned rice_parameter, + unsigned rice_parameter_limit, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool do_escape_coding, @@ -219,6 +220,7 @@ static unsigned evaluate_lpc_subframe_( unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, + unsigned rice_parameter_limit, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool do_escape_coding, @@ -244,12 +246,13 @@ static unsigned find_best_partition_order_( unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, + unsigned rice_parameter_limit, unsigned min_partition_order, unsigned max_partition_order, unsigned bps, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, - FLAC__EntropyCodingMethod_PartitionedRice *best_partitioned_rice + FLAC__EntropyCodingMethod *best_ecm ); static void precompute_partition_info_sums_( @@ -280,6 +283,7 @@ static FLAC__bool set_partitioned_rice_( const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, + const unsigned rice_parameter_limit, const unsigned rice_parameter_search_dist, const unsigned partition_order, const FLAC__bool search_for_escapes, @@ -3194,6 +3198,8 @@ FLAC__bool process_subframe_( unsigned rice_parameter; unsigned _candidate_bits, _best_bits; unsigned _best_subframe; + /* only use RICE2 partitions if stream bps > 16 */ + const unsigned rice_parameter_limit = FLAC__stream_encoder_get_bits_per_sample(encoder) > 16? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; FLAC__ASSERT(frame_header->blocksize > 0); @@ -3256,11 +3262,11 @@ FLAC__bool process_subframe_( rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > FLAC__FP_ZERO)? (unsigned)FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]+FLAC__FP_ONE_HALF) : 0; /* 0.5 is for rounding */ #endif rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */ - if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { + if(rice_parameter >= rice_parameter_limit) { #ifdef DEBUG_VERBOSE - fprintf(stderr, "clipping rice_parameter (%u -> %u) @0\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); + fprintf(stderr, "clipping rice_parameter (%u -> %u) @0\n", rice_parameter, rice_parameter_limit - 1); #endif - rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; + rice_parameter = rice_parameter_limit - 1; } _candidate_bits = evaluate_fixed_subframe_( @@ -3273,6 +3279,7 @@ FLAC__bool process_subframe_( subframe_bps, fixed_order, rice_parameter, + rice_parameter_limit, min_partition_order, max_partition_order, encoder->protected_->do_escape_coding, @@ -3327,11 +3334,11 @@ FLAC__bool process_subframe_( 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 */ rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */ - if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { + if(rice_parameter >= rice_parameter_limit) { #ifdef DEBUG_VERBOSE - fprintf(stderr, "clipping rice_parameter (%u -> %u) @1\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); + fprintf(stderr, "clipping rice_parameter (%u -> %u) @1\n", rice_parameter, rice_parameter_limit - 1); #endif - rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; + rice_parameter = rice_parameter_limit - 1; } if(encoder->protected_->do_qlp_coeff_prec_search) { min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION; @@ -3360,6 +3367,7 @@ FLAC__bool process_subframe_( lpc_order, qlp_coeff_precision, rice_parameter, + rice_parameter_limit, min_partition_order, max_partition_order, encoder->protected_->do_escape_coding, @@ -3499,6 +3507,7 @@ unsigned evaluate_fixed_subframe_( unsigned subframe_bps, unsigned order, unsigned rice_parameter, + unsigned rice_parameter_limit, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool do_escape_coding, @@ -3527,12 +3536,13 @@ unsigned evaluate_fixed_subframe_( residual_samples, order, rice_parameter, + rice_parameter_limit, min_partition_order, max_partition_order, subframe_bps, do_escape_coding, rice_parameter_search_dist, - &subframe->data.fixed.entropy_coding_method.data.partitioned_rice + &subframe->data.fixed.entropy_coding_method ); subframe->data.fixed.order = order; @@ -3561,6 +3571,7 @@ unsigned evaluate_lpc_subframe_( unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, + unsigned rice_parameter_limit, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool do_escape_coding, @@ -3608,12 +3619,13 @@ unsigned evaluate_lpc_subframe_( residual_samples, order, rice_parameter, + rice_parameter_limit, min_partition_order, max_partition_order, subframe_bps, do_escape_coding, rice_parameter_search_dist, - &subframe->data.lpc.entropy_coding_method.data.partitioned_rice + &subframe->data.lpc.entropy_coding_method ); subframe->data.lpc.order = order; @@ -3666,16 +3678,18 @@ unsigned find_best_partition_order_( unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, + unsigned rice_parameter_limit, unsigned min_partition_order, unsigned max_partition_order, unsigned bps, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, - FLAC__EntropyCodingMethod_PartitionedRice *best_partitioned_rice + FLAC__EntropyCodingMethod *best_ecm ) { unsigned residual_bits, best_residual_bits = 0; unsigned best_parameters_index = 0; + unsigned best_partition_order = 0; const unsigned blocksize = residual_samples + predictor_order; max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(max_partition_order, blocksize, predictor_order); @@ -3701,6 +3715,7 @@ unsigned find_best_partition_order_( residual_samples, predictor_order, rice_parameter, + rice_parameter_limit, rice_parameter_search_dist, (unsigned)partition_order, do_escape_coding, @@ -3716,20 +3731,37 @@ unsigned find_best_partition_order_( if(best_residual_bits == 0 || residual_bits < best_residual_bits) { best_residual_bits = residual_bits; best_parameters_index = !best_parameters_index; - best_partitioned_rice->order = partition_order; + best_partition_order = partition_order; } } } - /* - * We are allowed to de-const the pointer based on our special knowledge; - * it is const to the outside world. - */ + best_ecm->data.partitioned_rice.order = best_partition_order; + { - FLAC__EntropyCodingMethod_PartitionedRiceContents* best_partitioned_rice_contents = (FLAC__EntropyCodingMethod_PartitionedRiceContents*)best_partitioned_rice->contents; - FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(best_partitioned_rice_contents, max(6, best_partitioned_rice->order)); - memcpy(best_partitioned_rice_contents->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, sizeof(unsigned)*(1<<(best_partitioned_rice->order))); - memcpy(best_partitioned_rice_contents->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, sizeof(unsigned)*(1<<(best_partitioned_rice->order))); + /* + * We are allowed to de-const the pointer based on our special + * knowledge; it is const to the outside world. + */ + FLAC__EntropyCodingMethod_PartitionedRiceContents* prc = (FLAC__EntropyCodingMethod_PartitionedRiceContents*)best_ecm->data.partitioned_rice.contents; + unsigned partition; + + /* save best parameters and raw_bits */ + FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(prc, max(6, best_partition_order)); + memcpy(prc->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, sizeof(unsigned)*(1<<(best_partition_order))); + if(do_escape_coding) + memcpy(prc->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, sizeof(unsigned)*(1<<(best_partition_order))); + /* + * Now need to check if the type should be changed to + * FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 based on the + * size of the rice parameters. + */ + for(partition = 0; partition < (1u<parameters[partition] >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { + best_ecm->type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2; + break; + } + } } return best_residual_bits; @@ -3882,7 +3914,7 @@ static FLaC__INLINE unsigned count_rice_bits_in_partition_( ) { unsigned i, partition_bits = - FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + /* actually could end up being FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN but err on side of 16bps */ (1+rice_parameter) * partition_samples /* 1 for unary stop bit + rice_parameter for the binary portion */ ; for(i = 0; i < partition_samples; i++) @@ -3897,7 +3929,7 @@ static FLaC__INLINE unsigned count_rice_bits_in_partition_( ) { return - FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + /* actually could end up being FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN but err on side of 16bps */ (1+rice_parameter) * partition_samples + /* 1 for unary stop bit + rice_parameter for the binary portion */ ( rice_parameter? @@ -3924,6 +3956,7 @@ FLAC__bool set_partitioned_rice_( const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, + const unsigned rice_parameter_limit, const unsigned rice_parameter_search_dist, const unsigned partition_order, const FLAC__bool search_for_escapes, @@ -3941,7 +3974,8 @@ FLAC__bool set_partitioned_rice_( (void)rice_parameter_search_dist; #endif - FLAC__ASSERT(suggested_rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER); + FLAC__ASSERT(suggested_rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER); + FLAC__ASSERT(rice_parameter_limit <= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER); FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, max(6, partition_order)); parameters = partitioned_rice_contents->parameters; @@ -3956,11 +3990,11 @@ FLAC__bool set_partitioned_rice_( else min_rice_parameter = suggested_rice_parameter - rice_parameter_search_dist; max_rice_parameter = suggested_rice_parameter + rice_parameter_search_dist; - if(max_rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { + if(max_rice_parameter >= rice_parameter_limit) { #ifdef DEBUG_VERBOSE - fprintf(stderr, "clipping rice_parameter (%u -> %u) @5\n", max_rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); + fprintf(stderr, "clipping rice_parameter (%u -> %u) @5\n", max_rice_parameter, rice_parameter_limit - 1); #endif - max_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; + max_rice_parameter = rice_parameter_limit - 1; } } else @@ -3983,12 +4017,14 @@ FLAC__bool set_partitioned_rice_( } #endif if(search_for_escapes) { - partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[0] * residual_samples; + partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[0] * residual_samples; if(partition_bits <= best_partition_bits) { raw_bits[0] = raw_bits_per_partition[0]; - best_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; + best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */ best_partition_bits = partition_bits; } + else + raw_bits[0] = 0; } parameters[0] = best_rice_parameter; bits_ += best_partition_bits; @@ -4017,11 +4053,11 @@ FLAC__bool set_partitioned_rice_( */ for(rice_parameter = 0, k = partition_samples; k < mean; rice_parameter++, k <<= 1) ; - if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { + if(rice_parameter >= rice_parameter_limit) { #ifdef DEBUG_VERBOSE - fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); + fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1); #endif - rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; + rice_parameter = rice_parameter_limit - 1; } best_partition_bits = (unsigned)(-1); @@ -4032,11 +4068,11 @@ FLAC__bool set_partitioned_rice_( else min_rice_parameter = rice_parameter - rice_parameter_search_dist; max_rice_parameter = rice_parameter + rice_parameter_search_dist; - if(max_rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { + if(max_rice_parameter >= rice_parameter_limit) { #ifdef DEBUG_VERBOSE - fprintf(stderr, "clipping rice_parameter (%u -> %u) @7\n", max_rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); + fprintf(stderr, "clipping rice_parameter (%u -> %u) @7\n", max_rice_parameter, rice_parameter_limit - 1); #endif - max_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; + max_rice_parameter = rice_parameter_limit - 1; } } else @@ -4057,12 +4093,14 @@ FLAC__bool set_partitioned_rice_( } #endif if(search_for_escapes) { - partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples; + partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples; if(partition_bits <= best_partition_bits) { raw_bits[partition] = raw_bits_per_partition[partition]; - best_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; + best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */ best_partition_bits = partition_bits; } + else + raw_bits[partition] = 0; } parameters[partition] = best_rice_parameter; bits_ += best_partition_bits; diff --git a/src/libFLAC/stream_encoder_framing.c b/src/libFLAC/stream_encoder_framing.c index 6873dfc4..939955bf 100644 --- a/src/libFLAC/stream_encoder_framing.c +++ b/src/libFLAC/stream_encoder_framing.c @@ -45,7 +45,7 @@ #define max(x,y) ((x)>(y)?(x):(y)) static FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCodingMethod *method); -static FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order); +static FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order, const FLAC__bool is_extended); FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw) { @@ -229,7 +229,7 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_RESERVED_LEN)) return false; - if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN)) + if(!FLAC__bitwriter_write_raw_uint32(bw, (header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER)? 0 : 1, FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN)) return false; FLAC__ASSERT(header->blocksize > 0 && header->blocksize <= FLAC__MAX_BLOCK_SIZE); @@ -253,10 +253,8 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit default: if(header->blocksize <= 0x100) blocksize_hint = u = 6; - else if(header->blocksize <= 0x10000) - blocksize_hint = u = 7; else - u = 0; + blocksize_hint = u = 7; break; } if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BLOCK_SIZE_LEN)) @@ -265,14 +263,17 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit FLAC__ASSERT(FLAC__format_sample_rate_is_valid(header->sample_rate)); sample_rate_hint = 0; switch(header->sample_rate) { - case 8000: u = 4; break; - case 16000: u = 5; break; - case 22050: u = 6; break; - case 24000: u = 7; break; - case 32000: u = 8; break; - case 44100: u = 9; break; - case 48000: u = 10; break; - case 96000: u = 11; break; + case 88200: u = 1; break; + case 176400: u = 2; break; + case 192000: u = 3; break; + case 8000: u = 4; break; + case 16000: u = 5; break; + case 22050: u = 6; break; + case 24000: u = 7; break; + case 32000: u = 8; break; + case 44100: u = 9; break; + case 48000: u = 10; break; + case 96000: u = 11; break; default: if(header->sample_rate <= 255000 && header->sample_rate % 1000 == 0) sample_rate_hint = u = 12; @@ -325,9 +326,14 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_ZERO_PAD_LEN)) return false; - FLAC__ASSERT(header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER); - if(!FLAC__bitwriter_write_utf8_uint32(bw, header->number.frame_number)) - return false; + if(header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER) { + if(!FLAC__bitwriter_write_utf8_uint32(bw, header->number.frame_number)) + return false; + } + else { + if(!FLAC__bitwriter_write_utf8_uint64(bw, header->number.sample_number)) + return false; + } if(blocksize_hint) if(!FLAC__bitwriter_write_raw_uint32(bw, header->blocksize-1, (blocksize_hint==6)? 8:16)) @@ -388,7 +394,17 @@ FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsign return false; switch(subframe->entropy_coding_method.type) { case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: - if(!add_residual_partitioned_rice_(bw, subframe->residual, residual_samples, subframe->order, subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, subframe->entropy_coding_method.data.partitioned_rice.order)) + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: + if(!add_residual_partitioned_rice_( + bw, + subframe->residual, + residual_samples, + subframe->order, + subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, + subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, + subframe->entropy_coding_method.data.partitioned_rice.order, + /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 + )) return false; break; default: @@ -424,7 +440,17 @@ FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned r return false; switch(subframe->entropy_coding_method.type) { case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: - if(!add_residual_partitioned_rice_(bw, subframe->residual, residual_samples, subframe->order, subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, subframe->entropy_coding_method.data.partitioned_rice.order)) + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: + if(!add_residual_partitioned_rice_( + bw, + subframe->residual, + residual_samples, + subframe->order, + subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, + subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, + subframe->entropy_coding_method.data.partitioned_rice.order, + /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 + )) return false; break; default: @@ -458,6 +484,7 @@ FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCo return false; switch(method->type) { case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: if(!FLAC__bitwriter_write_raw_uint32(bw, method->data.partitioned_rice.order, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) return false; break; @@ -467,18 +494,24 @@ FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCo return true; } -FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order) +FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order, const FLAC__bool is_extended) { + const unsigned plen = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; + const unsigned pesc = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; + if(partition_order == 0) { unsigned i; - if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)) - return false; - if(rice_parameters[0] < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { + if(raw_bits[0] == 0) { + if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[0], plen)) + return false; if(!FLAC__bitwriter_write_rice_signed_block(bw, residual, residual_samples, rice_parameters[0])) return false; } else { + FLAC__ASSERT(rice_parameters[0] == 0); + if(!FLAC__bitwriter_write_raw_uint32(bw, pesc, plen)) + return false; if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN)) return false; for(i = 0; i < residual_samples; i++) { @@ -493,17 +526,19 @@ FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 unsigned partition_samples; const unsigned default_partition_samples = (residual_samples+predictor_order) >> partition_order; for(i = 0; i < (1u<