#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#ifdef _WIN32
#include <windows.h>
#include <io.h>
#endif
#include "share/compat.h"
#include "FLAC/assert.h"
#include "FLAC/stream_decoder.h"
#include "protected/stream_encoder.h"
#include "private/bitwriter.h"
#include "private/bitmath.h"
#include "private/crc.h"
#include "private/cpu.h"
#include "private/fixed.h"
#include "private/format.h"
#include "private/lpc.h"
#include "private/md5.h"
#include "private/memory.h"
#include "private/macros.h"
#if FLAC__HAS_OGG
#include "private/ogg_helper.h"
#include "private/ogg_mapping.h"
#endif
#include "private/stream_encoder.h"
#include "private/stream_encoder_framing.h"
#include "private/window.h"
#include "share/alloc.h"
#include "share/private.h"
#undef EXACT_RICE_BITS_CALCULATION
#undef ENABLE_RICE_PARAMETER_SEARCH
verify_input_fifo;
verify_output;
EncoderStateHint;
static const struct CompressionLevels { … } compression_levels_[] = …;
static void set_defaults_(FLAC__StreamEncoder *encoder);
static void free_(FLAC__StreamEncoder *encoder);
static FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, uint32_t new_blocksize);
static FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, uint32_t samples, FLAC__bool is_last_block);
static FLAC__StreamEncoderWriteStatus write_frame_(FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, uint32_t samples, FLAC__bool is_last_block);
static void update_metadata_(const FLAC__StreamEncoder *encoder);
#if FLAC__HAS_OGG
static void update_ogg_metadata_(FLAC__StreamEncoder *encoder);
#endif
static FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_block);
static FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder);
static FLAC__bool process_subframe_(
FLAC__StreamEncoder *encoder,
uint32_t min_partition_order,
uint32_t max_partition_order,
const FLAC__FrameHeader *frame_header,
uint32_t subframe_bps,
const void *integer_signal,
FLAC__Subframe *subframe[2],
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2],
FLAC__int32 *residual[2],
uint32_t *best_subframe,
uint32_t *best_bits
);
static FLAC__bool add_subframe_(
FLAC__StreamEncoder *encoder,
uint32_t blocksize,
uint32_t subframe_bps,
const FLAC__Subframe *subframe,
FLAC__BitWriter *frame
);
static uint32_t evaluate_constant_subframe_(
FLAC__StreamEncoder *encoder,
const FLAC__int64 signal,
uint32_t blocksize,
uint32_t subframe_bps,
FLAC__Subframe *subframe
);
static uint32_t evaluate_fixed_subframe_(
FLAC__StreamEncoder *encoder,
const void *signal,
FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[],
uint32_t raw_bits_per_partition[],
uint32_t blocksize,
uint32_t subframe_bps,
uint32_t order,
uint32_t rice_parameter_limit,
uint32_t min_partition_order,
uint32_t max_partition_order,
FLAC__bool do_escape_coding,
uint32_t rice_parameter_search_dist,
FLAC__Subframe *subframe,
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
);
#ifndef FLAC__INTEGER_ONLY_LIBRARY
static uint32_t evaluate_lpc_subframe_(
FLAC__StreamEncoder *encoder,
const void *signal,
FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[],
uint32_t raw_bits_per_partition[],
const FLAC__real lp_coeff[],
uint32_t blocksize,
uint32_t subframe_bps,
uint32_t order,
uint32_t qlp_coeff_precision,
uint32_t rice_parameter_limit,
uint32_t min_partition_order,
uint32_t max_partition_order,
FLAC__bool do_escape_coding,
uint32_t rice_parameter_search_dist,
FLAC__Subframe *subframe,
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
);
#endif
static uint32_t evaluate_verbatim_subframe_(
FLAC__StreamEncoder *encoder,
const void *signal,
uint32_t blocksize,
uint32_t subframe_bps,
FLAC__Subframe *subframe
);
static uint32_t find_best_partition_order_(
struct FLAC__StreamEncoderPrivate *private_,
const FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[],
uint32_t raw_bits_per_partition[],
uint32_t residual_samples,
uint32_t predictor_order,
uint32_t rice_parameter_limit,
uint32_t min_partition_order,
uint32_t max_partition_order,
uint32_t bps,
FLAC__bool do_escape_coding,
uint32_t rice_parameter_search_dist,
FLAC__EntropyCodingMethod *best_ecm
);
static void precompute_partition_info_sums_(
const FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[],
uint32_t residual_samples,
uint32_t predictor_order,
uint32_t min_partition_order,
uint32_t max_partition_order,
uint32_t bps
);
static void precompute_partition_info_escapes_(
const FLAC__int32 residual[],
uint32_t raw_bits_per_partition[],
uint32_t residual_samples,
uint32_t predictor_order,
uint32_t min_partition_order,
uint32_t max_partition_order
);
static FLAC__bool set_partitioned_rice_(
#ifdef EXACT_RICE_BITS_CALCULATION
const FLAC__int32 residual[],
#endif
const FLAC__uint64 abs_residual_partition_sums[],
const uint32_t raw_bits_per_partition[],
const uint32_t residual_samples,
const uint32_t predictor_order,
const uint32_t rice_parameter_limit,
const uint32_t rice_parameter_search_dist,
const uint32_t partition_order,
const FLAC__bool search_for_escapes,
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents,
uint32_t *bits
);
static uint32_t get_wasted_bits_(FLAC__int32 signal[], uint32_t samples);
static uint32_t get_wasted_bits_wide_(FLAC__int64 signal_wide[], FLAC__int32 signal[], uint32_t samples);
static void append_to_verify_fifo_(
verify_input_fifo *fifo,
const FLAC__int32 * const input[],
uint32_t input_offset,
uint32_t channels,
uint32_t wide_samples
);
static void append_to_verify_fifo_interleaved_(
verify_input_fifo *fifo,
const FLAC__int32 input[],
uint32_t input_offset,
uint32_t channels,
uint32_t wide_samples
);
static FLAC__StreamDecoderReadStatus verify_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
static FLAC__StreamDecoderWriteStatus verify_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
static void verify_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
static void verify_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
static FLAC__StreamEncoderReadStatus file_read_callback_(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
static FLAC__StreamEncoderSeekStatus file_seek_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
static FLAC__StreamEncoderTellStatus file_tell_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
static FLAC__StreamEncoderWriteStatus file_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame, void *client_data);
static FILE *get_binary_stdout_(void);
FLAC__StreamEncoderPrivate;
FLAC_API const char * const FLAC__StreamEncoderStateString[] = …;
FLAC_API const char * const FLAC__StreamEncoderInitStatusString[] = …;
FLAC_API const char * const FLAC__StreamEncoderReadStatusString[] = …;
FLAC_API const char * const FLAC__StreamEncoderWriteStatusString[] = …;
FLAC_API const char * const FLAC__StreamEncoderSeekStatusString[] = …;
FLAC_API const char * const FLAC__StreamEncoderTellStatusString[] = …;
static const uint32_t OVERREAD_ = …;
FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(void)
{ … }
FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder)
{ … }
static FLAC__StreamEncoderInitStatus init_stream_internal_(
FLAC__StreamEncoder *encoder,
FLAC__StreamEncoderReadCallback read_callback,
FLAC__StreamEncoderWriteCallback write_callback,
FLAC__StreamEncoderSeekCallback seek_callback,
FLAC__StreamEncoderTellCallback tell_callback,
FLAC__StreamEncoderMetadataCallback metadata_callback,
void *client_data,
FLAC__bool is_ogg
)
{ … }
FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_stream(
FLAC__StreamEncoder *encoder,
FLAC__StreamEncoderWriteCallback write_callback,
FLAC__StreamEncoderSeekCallback seek_callback,
FLAC__StreamEncoderTellCallback tell_callback,
FLAC__StreamEncoderMetadataCallback metadata_callback,
void *client_data
)
{ … }
FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_stream(
FLAC__StreamEncoder *encoder,
FLAC__StreamEncoderReadCallback read_callback,
FLAC__StreamEncoderWriteCallback write_callback,
FLAC__StreamEncoderSeekCallback seek_callback,
FLAC__StreamEncoderTellCallback tell_callback,
FLAC__StreamEncoderMetadataCallback metadata_callback,
void *client_data
)
{ … }
static FLAC__StreamEncoderInitStatus init_FILE_internal_(
FLAC__StreamEncoder *encoder,
FILE *file,
FLAC__StreamEncoderProgressCallback progress_callback,
void *client_data,
FLAC__bool is_ogg
)
{ … }
FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_FILE(
FLAC__StreamEncoder *encoder,
FILE *file,
FLAC__StreamEncoderProgressCallback progress_callback,
void *client_data
)
{ … }
FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_FILE(
FLAC__StreamEncoder *encoder,
FILE *file,
FLAC__StreamEncoderProgressCallback progress_callback,
void *client_data
)
{ … }
static FLAC__StreamEncoderInitStatus init_file_internal_(
FLAC__StreamEncoder *encoder,
const char *filename,
FLAC__StreamEncoderProgressCallback progress_callback,
void *client_data,
FLAC__bool is_ogg
)
{ … }
FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_file(
FLAC__StreamEncoder *encoder,
const char *filename,
FLAC__StreamEncoderProgressCallback progress_callback,
void *client_data
)
{ … }
FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_file(
FLAC__StreamEncoder *encoder,
const char *filename,
FLAC__StreamEncoderProgressCallback progress_callback,
void *client_data
)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_ogg_serial_number(FLAC__StreamEncoder *encoder, long value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncoder *encoder, FLAC__bool value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_channels(FLAC__StreamEncoder *encoder, uint32_t value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_bits_per_sample(FLAC__StreamEncoder *encoder, uint32_t value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *encoder, uint32_t value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_compression_level(FLAC__StreamEncoder *encoder, uint32_t value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *encoder, uint32_t value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_do_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *encoder, const char *specification)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_max_lpc_order(FLAC__StreamEncoder *encoder, uint32_t value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_qlp_coeff_precision(FLAC__StreamEncoder *encoder, uint32_t value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_do_qlp_coeff_prec_search(FLAC__StreamEncoder *encoder, FLAC__bool value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_do_escape_coding(FLAC__StreamEncoder *encoder, FLAC__bool value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_do_exhaustive_model_search(FLAC__StreamEncoder *encoder, FLAC__bool value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_min_residual_partition_order(FLAC__StreamEncoder *encoder, uint32_t value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_max_residual_partition_order(FLAC__StreamEncoder *encoder, uint32_t value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_rice_parameter_search_dist(FLAC__StreamEncoder *encoder, uint32_t value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_total_samples_estimate(FLAC__StreamEncoder *encoder, FLAC__uint64 value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, uint32_t num_blocks)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_set_limit_min_bitrate(FLAC__StreamEncoder *encoder, FLAC__bool value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_disable_instruction_set(FLAC__StreamEncoder *encoder, FLAC__bool value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value)
{ … }
FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_get_state(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API FLAC__StreamDecoderState FLAC__stream_encoder_get_verify_decoder_state(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API const char *FLAC__stream_encoder_get_resolved_state_string(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API void FLAC__stream_encoder_get_verify_decoder_error_stats(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_sample, uint32_t *frame_number, uint32_t *channel, uint32_t *sample, FLAC__int32 *expected, FLAC__int32 *got)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_get_verify(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_get_streamable_subset(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_get_do_md5(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API uint32_t FLAC__stream_encoder_get_channels(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API uint32_t FLAC__stream_encoder_get_bits_per_sample(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API uint32_t FLAC__stream_encoder_get_sample_rate(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API uint32_t FLAC__stream_encoder_get_blocksize(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_get_do_mid_side_stereo(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_get_loose_mid_side_stereo(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API uint32_t FLAC__stream_encoder_get_max_lpc_order(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API uint32_t FLAC__stream_encoder_get_qlp_coeff_precision(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_get_do_escape_coding(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_get_do_exhaustive_model_search(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API uint32_t FLAC__stream_encoder_get_min_residual_partition_order(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API uint32_t FLAC__stream_encoder_get_max_residual_partition_order(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API uint32_t FLAC__stream_encoder_get_rice_parameter_search_dist(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_get_limit_min_bitrate(const FLAC__StreamEncoder *encoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], uint32_t samples)
{ … }
FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], uint32_t samples)
{ … }
void set_defaults_(FLAC__StreamEncoder *encoder)
{ … }
void free_(FLAC__StreamEncoder *encoder)
{ … }
FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, uint32_t new_blocksize)
{ … }
FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, uint32_t samples, FLAC__bool is_last_block)
{ … }
FLAC__StreamEncoderWriteStatus write_frame_(FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, uint32_t samples, FLAC__bool is_last_block)
{ … }
void update_metadata_(const FLAC__StreamEncoder *encoder)
{ … }
#if FLAC__HAS_OGG
void update_ogg_metadata_(FLAC__StreamEncoder *encoder)
{
static const uint32_t FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH =
FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH +
FLAC__OGG_MAPPING_MAGIC_LENGTH +
FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH +
FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH +
FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH +
FLAC__STREAM_SYNC_LENGTH
;
FLAC__byte b[flac_max(6u, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo;
const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
const uint32_t min_framesize = metadata->data.stream_info.min_framesize;
const uint32_t max_framesize = metadata->data.stream_info.max_framesize;
ogg_page page;
FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
FLAC__ASSERT(0 != encoder->private_->seek_callback);
if(encoder->private_->seek_callback(encoder, 0, encoder->private_->client_data) == FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED)
return;
simple_ogg_page__init(&page);
if(!simple_ogg_page__get_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
simple_ogg_page__clear(&page);
return;
}
{
const uint32_t md5_offset =
FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH +
FLAC__STREAM_METADATA_HEADER_LENGTH +
(
FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN +
FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
) / 8;
if(md5_offset + 16 > (uint32_t)page.body_len) {
encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
simple_ogg_page__clear(&page);
return;
}
memcpy(page.body + md5_offset, metadata->data.stream_info.md5sum, 16);
}
{
const uint32_t total_samples_byte_offset =
FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH +
FLAC__STREAM_METADATA_HEADER_LENGTH +
(
FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
- 4
) / 8;
if(total_samples_byte_offset + 5 > (uint32_t)page.body_len) {
encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
simple_ogg_page__clear(&page);
return;
}
b[0] = (FLAC__byte)page.body[total_samples_byte_offset] & 0xF0;
b[0] |= (FLAC__byte)((samples >> 32) & 0x0F);
b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
b[4] = (FLAC__byte)(samples & 0xFF);
memcpy(page.body + total_samples_byte_offset, b, 5);
}
{
const uint32_t min_framesize_offset =
FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH +
FLAC__STREAM_METADATA_HEADER_LENGTH +
(
FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN
) / 8;
if(min_framesize_offset + 6 > (uint32_t)page.body_len) {
encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
simple_ogg_page__clear(&page);
return;
}
b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
b[2] = (FLAC__byte)(min_framesize & 0xFF);
b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
b[5] = (FLAC__byte)(max_framesize & 0xFF);
memcpy(page.body + min_framesize_offset, b, 6);
}
if(!simple_ogg_page__set_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
simple_ogg_page__clear(&page);
return;
}
simple_ogg_page__clear(&page);
if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) {
uint32_t i;
FLAC__byte *p;
FLAC__format_seektable_sort(encoder->private_->seek_table);
FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table));
simple_ogg_page__init(&page);
if(!simple_ogg_page__get_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
simple_ogg_page__clear(&page);
return;
}
if((FLAC__STREAM_METADATA_HEADER_LENGTH + 18*encoder->private_->seek_table->num_points) != (uint32_t)page.body_len) {
encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
simple_ogg_page__clear(&page);
return;
}
for(i = 0, p = page.body + FLAC__STREAM_METADATA_HEADER_LENGTH; i < encoder->private_->seek_table->num_points; i++, p += 18) {
FLAC__uint64 xx;
uint32_t x;
xx = encoder->private_->seek_table->points[i].sample_number;
b[7] = (FLAC__byte)xx; xx >>= 8;
b[6] = (FLAC__byte)xx; xx >>= 8;
b[5] = (FLAC__byte)xx; xx >>= 8;
b[4] = (FLAC__byte)xx; xx >>= 8;
b[3] = (FLAC__byte)xx; xx >>= 8;
b[2] = (FLAC__byte)xx; xx >>= 8;
b[1] = (FLAC__byte)xx; xx >>= 8;
b[0] = (FLAC__byte)xx; xx >>= 8;
xx = encoder->private_->seek_table->points[i].stream_offset;
b[15] = (FLAC__byte)xx; xx >>= 8;
b[14] = (FLAC__byte)xx; xx >>= 8;
b[13] = (FLAC__byte)xx; xx >>= 8;
b[12] = (FLAC__byte)xx; xx >>= 8;
b[11] = (FLAC__byte)xx; xx >>= 8;
b[10] = (FLAC__byte)xx; xx >>= 8;
b[9] = (FLAC__byte)xx; xx >>= 8;
b[8] = (FLAC__byte)xx; xx >>= 8;
x = encoder->private_->seek_table->points[i].frame_samples;
b[17] = (FLAC__byte)x; x >>= 8;
b[16] = (FLAC__byte)x; x >>= 8;
memcpy(p, b, 18);
}
if(!simple_ogg_page__set_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
simple_ogg_page__clear(&page);
return;
}
simple_ogg_page__clear(&page);
}
}
#endif
FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_block)
{ … }
FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder)
{ … }
static inline void set_next_subdivide_tukey(FLAC__int32 parts, uint32_t * apodizations, uint32_t * current_depth, uint32_t * current_part){ … }
FLAC__bool process_subframe_(
FLAC__StreamEncoder *encoder,
uint32_t min_partition_order,
uint32_t max_partition_order,
const FLAC__FrameHeader *frame_header,
uint32_t subframe_bps,
const void *integer_signal,
FLAC__Subframe *subframe[2],
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2],
FLAC__int32 *residual[2],
uint32_t *best_subframe,
uint32_t *best_bits
)
{ … }
FLAC__bool add_subframe_(
FLAC__StreamEncoder *encoder,
uint32_t blocksize,
uint32_t subframe_bps,
const FLAC__Subframe *subframe,
FLAC__BitWriter *frame
)
{ … }
#define SPOTCHECK_ESTIMATE …
#if SPOTCHECK_ESTIMATE
static void spotcheck_subframe_estimate_(
FLAC__StreamEncoder *encoder,
uint32_t blocksize,
uint32_t subframe_bps,
const FLAC__Subframe *subframe,
uint32_t estimate
)
{
FLAC__bool ret;
FLAC__BitWriter *frame = FLAC__bitwriter_new();
if(frame == 0) {
fprintf(stderr, "EST: can't allocate frame\n");
return;
}
if(!FLAC__bitwriter_init(frame)) {
fprintf(stderr, "EST: can't init frame\n");
return;
}
ret = add_subframe_(encoder, blocksize, subframe_bps, subframe, frame);
FLAC__ASSERT(ret);
{
const uint32_t actual = FLAC__bitwriter_get_input_bits_unconsumed(frame);
if(estimate != actual)
fprintf(stderr, "EST: bad, frame#%u sub#%%d type=%8s est=%u, actual=%u, delta=%d\n", encoder->private_->current_frame_number, FLAC__SubframeTypeString[subframe->type], estimate, actual, (int)actual-(int)estimate);
}
FLAC__bitwriter_delete(frame);
}
#endif
uint32_t evaluate_constant_subframe_(
FLAC__StreamEncoder *encoder,
const FLAC__int64 signal,
uint32_t blocksize,
uint32_t subframe_bps,
FLAC__Subframe *subframe
)
{ … }
uint32_t evaluate_fixed_subframe_(
FLAC__StreamEncoder *encoder,
const void *signal,
FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[],
uint32_t raw_bits_per_partition[],
uint32_t blocksize,
uint32_t subframe_bps,
uint32_t order,
uint32_t rice_parameter_limit,
uint32_t min_partition_order,
uint32_t max_partition_order,
FLAC__bool do_escape_coding,
uint32_t rice_parameter_search_dist,
FLAC__Subframe *subframe,
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
)
{ … }
#ifndef FLAC__INTEGER_ONLY_LIBRARY
uint32_t evaluate_lpc_subframe_(
FLAC__StreamEncoder *encoder,
const void *signal,
FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[],
uint32_t raw_bits_per_partition[],
const FLAC__real lp_coeff[],
uint32_t blocksize,
uint32_t subframe_bps,
uint32_t order,
uint32_t qlp_coeff_precision,
uint32_t rice_parameter_limit,
uint32_t min_partition_order,
uint32_t max_partition_order,
FLAC__bool do_escape_coding,
uint32_t rice_parameter_search_dist,
FLAC__Subframe *subframe,
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
)
{ … }
#endif
uint32_t evaluate_verbatim_subframe_(
FLAC__StreamEncoder *encoder,
const void *signal,
uint32_t blocksize,
uint32_t subframe_bps,
FLAC__Subframe *subframe
)
{ … }
uint32_t find_best_partition_order_(
FLAC__StreamEncoderPrivate *private_,
const FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[],
uint32_t raw_bits_per_partition[],
uint32_t residual_samples,
uint32_t predictor_order,
uint32_t rice_parameter_limit,
uint32_t min_partition_order,
uint32_t max_partition_order,
uint32_t bps,
FLAC__bool do_escape_coding,
uint32_t rice_parameter_search_dist,
FLAC__EntropyCodingMethod *best_ecm
)
{ … }
void precompute_partition_info_sums_(
const FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[],
uint32_t residual_samples,
uint32_t predictor_order,
uint32_t min_partition_order,
uint32_t max_partition_order,
uint32_t bps
)
{ … }
void precompute_partition_info_escapes_(
const FLAC__int32 residual[],
uint32_t raw_bits_per_partition[],
uint32_t residual_samples,
uint32_t predictor_order,
uint32_t min_partition_order,
uint32_t max_partition_order
)
{ … }
#ifdef EXACT_RICE_BITS_CALCULATION
static inline uint32_t count_rice_bits_in_partition_(
const uint32_t rice_parameter,
const uint32_t partition_samples,
const FLAC__int32 *residual
)
{
uint32_t i;
uint64_t partition_bits =
FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN +
(1+rice_parameter) * partition_samples
;
for(i = 0; i < partition_samples; i++)
partition_bits += ( (FLAC__uint32)((residual[i]<<1)^(residual[i]>>31)) >> rice_parameter );
return (uint32_t)(flac_min(partition_bits,UINT32_MAX));
}
#else
static inline uint32_t count_rice_bits_in_partition_(
const uint32_t rice_parameter,
const uint32_t partition_samples,
const FLAC__uint64 abs_residual_partition_sum
)
{ … }
#endif
FLAC__bool set_partitioned_rice_(
#ifdef EXACT_RICE_BITS_CALCULATION
const FLAC__int32 residual[],
#endif
const FLAC__uint64 abs_residual_partition_sums[],
const uint32_t raw_bits_per_partition[],
const uint32_t residual_samples,
const uint32_t predictor_order,
const uint32_t rice_parameter_limit,
const uint32_t rice_parameter_search_dist,
const uint32_t partition_order,
const FLAC__bool search_for_escapes,
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents,
uint32_t *bits
)
{ … }
uint32_t get_wasted_bits_(FLAC__int32 signal[], uint32_t samples)
{ … }
uint32_t get_wasted_bits_wide_(FLAC__int64 signal_wide[], FLAC__int32 signal[], uint32_t samples)
{ … }
void append_to_verify_fifo_(verify_input_fifo *fifo, const FLAC__int32 * const input[], uint32_t input_offset, uint32_t channels, uint32_t wide_samples)
{ … }
void append_to_verify_fifo_interleaved_(verify_input_fifo *fifo, const FLAC__int32 input[], uint32_t input_offset, uint32_t channels, uint32_t wide_samples)
{ … }
FLAC__StreamDecoderReadStatus verify_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
{ … }
FLAC__StreamDecoderWriteStatus verify_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
{ … }
void verify_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
{ … }
void verify_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
{ … }
FLAC__StreamEncoderReadStatus file_read_callback_(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
{ … }
FLAC__StreamEncoderSeekStatus file_seek_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
{ … }
FLAC__StreamEncoderTellStatus file_tell_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
{ … }
#ifdef FLAC__VALGRIND_TESTING
static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
size_t ret = fwrite(ptr, size, nmemb, stream);
if(!ferror(stream))
fflush(stream);
return ret;
}
#else
#define local__fwrite …
#endif
FLAC__StreamEncoderWriteStatus file_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame, void *client_data)
{ … }
FILE *get_binary_stdout_(void)
{ … }