use ;
use ;
use ;
use PhantomData;
use TryFrom;
use c_uint;
use ;
/// The [stream encoder](https://xiph.org/flac/api/group__flac__stream__encoder.html) can encode to native FLAC,
/// and optionally Ogg FLAC (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files.
///
/// The basic usage of this encoder is as follows:
/// * The program creates an instance of an encoder using
/// [`FlacEncoder::new()`](#method.new).
/// * The program overrides the default settings using functions in
/// [`FlacEncoderConfig`](struct.FlacEncoderConfig.html). At a minimum, the following
/// functions should be called:
/// * [`FlacEncoderConfig::channels()`](struct.FlacEncoderConfig.html#method.channels)
/// * [`FlacEncoderConfig::bits_per_sample()`](struct.FlacEncoderConfig.html#method.bits_per_sample)
/// * [`FlacEncoderConfig::sample_rate()`](struct.FlacEncoderConfig.html#method.sample_rate)
/// * [`FlacEncoderConfig::ogg_serial_number()`](struct.FlacEncoderConfig.html#method.ogg_serial_number)
/// (if encoding to Ogg FLAC)
/// * [`FlacEncoderConfig::total_samples_estimate()`](struct.FlacEncoderConfig.html#method.total_samples_estimate)
/// (if known)
/// * If the application wants to control the compression level or set its own
/// metadata, then the following should also be called:
/// * [`FlacEncoderConfig::compression_level()`](struct.FlacEncoderConfig.html#method.compression_level)
/// * [`FlacEncoderConfig::verify()`](struct.FlacEncoderConfig.html#method.verify)
/// * [`FlacEncoderConfig::metadata()`](struct.FlacEncoderConfig.html#method.metadata)
/// * The rest of the set functions should only be called if the client needs
/// exact control over how the audio is compressed; thorough understanding
/// of the FLAC format is necessary to achieve good results.
/// * The program initializes the instance to validate the settings and
/// prepare for encoding using
/// * [`FlacEncoderConfig::init_write()`](struct.FlacEncoderConfig.html#method.init_write), or
/// [`FlacEncoderConfig::init_file()`](struct.FlacEncoderConfig.html#method.init_file), or
/// [`FlacEncoderConfig::init_stdout()`](struct.FlacEncoderConfig.html#method.init_stdout) for native FLAC
/// * [`FlacEncoderConfig::init_write_ogg()`](struct.FlacEncoderConfig.html#method.init_write_ogg), or
/// [`FlacEncoderConfig::init_file_ogg()`](struct.FlacEncoderConfig.html#method.init_file_ogg), or
/// [`FlacEncoderConfig::init_stdout_ogg()`](struct.FlacEncoderConfig.html#method.init_stdout_ogg) for Ogg FLAC
/// * The program calls [`FlacEncoder::process()`](#method.process) or
/// [`FlacEncoder::process_interleaved()`](#method.process_interleaved) to encode data, which
/// subsequently calls the callbacks when there is encoder data ready
/// to be written.
/// * The program finishes the encoding with [`FlacEncoder::finish()`](#method.finish),
/// which causes the encoder to encode any data still in its input pipe,
/// update the metadata with the final encoding statistics if output
/// seeking is possible, and finally reset the encoder to the
/// uninitialized state.
/// Note: the stream is `finish()`ed when it's dropped, and any potential error is ignored.
/// * The instance may be used again or deleted with
/// [`FlacEncoder::delete()`](#method.delete).
/// Note: the stream is `delete()`ed when it's dropped.
///
/// In more detail, the stream encoder functions similarly to the
/// stream decoder, but has fewer
/// callbacks and more options. Typically the client will create a new
/// instance by calling [`FlacEncoder::new()`](#method.new), then set the necessary
/// parameters with functions on [`FlacEncoderConfig`](struct.FlacEncoderConfig.html), and initialize it by
/// calling one of the [`FlacEncoderConfig::init_*()`](struct.FlacEncoderConfig.html#method.init_write) functions.
///
/// Unlike the decoders, the stream encoder has many options that can
/// affect the speed and compression ratio. When setting these parameters
/// you should have some basic knowledge of the format (see the
/// user-level documentation or the formal description). The functions on
/// [`FlacEncoderConfig`](struct.FlacEncoderConfig.html) themselves do not validate the
/// values as many are interdependent. The [`FlacEncoderConfig::init_*()`](struct.FlacEncoderConfig.html#method.init_write)
/// functions will do this, so make sure to pay attention to the result
/// returned by [`FlacEncoderConfig::init_*()`](struct.FlacEncoderConfig.html#method.init_write) to make sure that it is
/// `Ok()`. Any parameters that are not set
/// before [`FlacEncoderConfig::init_*()`](struct.FlacEncoderConfig.html#method.init_write) will take on the defaults from
/// the constructor.
///
/// There are three initialization functions for native FLAC, one for
/// setting up the encoder to encode FLAC data to the client via
/// a `Write` stream, and two for encoding directly to a file.
///
/// For encoding via a `Write` stream, use [`FlacEncoderConfig::init_write()`](struct.FlacEncoderConfig.html#method.init_write).
/// You must also supply a `std::io::Write` stream which will be called anytime
/// there is raw encoded data to write. The client cannot seek the output due to
/// [RFC 2035](https://github.com/rust-lang/rfcs/issues/2035), so the
/// encoder cannot go back after encoding is finished to write back
/// information that was collected while encoding, like seek point offsets,
/// frame sizes, etc.
///
/// For encoding directly to a file, use [`FlacEncoderConfig::init_file()`](struct.FlacEncoderConfig.html#method.init_file).
/// Then you must only supply a UTF-8 filename; the encoder will handle all the callbacks
/// internally. You may also supply a progress callback for periodic
/// notification of the encoding progress.
///
/// There are three similarly-named init functions for encoding to Ogg
/// FLAC streams.
///
/// The call to [`FlacEncoderConfig::init_*()`](struct.FlacEncoderConfig.html#method.init_write) currently will also immediately
/// call write to the sink several times, once with the `fLaC` signature,
/// and once for each encoded metadata block. Note that for Ogg FLAC
/// encoding you will usually get at least twice the number of callbacks than
/// with native FLAC, one for the Ogg page header and one for the page body.
///
/// After initializing the instance, the client may feed audio data to the
/// encoder in one of two ways:
///
/// * Channel separate, through [`FlacEncoder::process()`](#method.process) - The client
/// will pass an slice of buffer slices, one for each channel, to
/// the encoder, each of the same length. The samples need not be
/// block-aligned, but each channel should have the same number of samples.
/// This function will allocate if the user supplies more than 8 channels.
/// * Channel interleaved, through
/// [`FlacEncoder::process_interleaved()`](#method.process_interleaved) - The client will pass a single
/// slice to data that is channel-interleaved (i.e. `channel0_sample0`,
/// `channel1_sample0`, ... , `channelN_sample0`, `channel0_sample1`, ...).
/// Again, the samples need not be block-aligned but they must be
/// sample-aligned, i.e. the first value should be `channel0_sample0` and
/// the last value `channelN_sampleM`.
///
/// Note that for either process call, each sample in the buffers should be a
/// signed integer, right-justified to the resolution set by
/// [`FlacEncoderConfig::bits_per_sample()`](struct.FlacEncoderConfig.html#method.bits_per_sample).
/// For example, if the resolution is 16 bits per sample, the samples should all be in the range [-32768,32767].
///
/// When the client is finished encoding data, it calls
/// [`FlacEncoder::finish()`](#method.finish), either explicitly or by dropping the encoder,
/// which causes the encoder to encode any
/// data still in its input pipe, and call the metadata callback with the
/// final encoding statistics. Then the instance may be deleted with
/// [`FlacEncoder::delete()`](#method.delete) by dropping the encoder, or initialized again to encode another
/// stream.
///
/// For programs that write their own metadata, but that do not know the
/// actual metadata until after encoding, it is advantageous to instruct
/// the encoder to write a PADDING block of the correct size, so that
/// instead of rewriting the whole stream after encoding, the program can
/// just overwrite the PADDING block. If only the maximum size of the
/// metadata is known, the program can write a slightly larger padding
/// block, then split it after encoding.
///
/// Make sure you understand how lengths are calculated. All FLAC metadata
/// blocks have a 4 byte header which contains the type and length. This
/// length does not include the 4 bytes of the header. See the format page
/// for the specification of metadata blocks and their lengths.
///
/// **Note**:<br />
/// If you are writing the FLAC data to a file via callbacks, make sure it
/// is open for update (e.g. mode "w+" for stdio streams). This is because
/// after the first encoding pass, the encoder will try to seek back to the
/// beginning of the stream, to the STREAMINFO block, to write some data
/// there. (If using [`FlacEncoderConfig::init_file()`](struct.FlacEncoderConfig.html#method.init_file), the file is managed internally.)
///
/// **Note**:<br />
/// [`FlacEncoder::finish()`](#method.finish) resets all settings to the constructor defaults.
StreamEncoderContainer, pub );