2015-03-18 1 views
0

Вот фрагмент кода из libavutil/samplefmt.h:Как кодировать 24-битный звук с помощью libav/ffmpeg?

/** 
* Audio Sample Formats 
* 
* @par 
* The data described by the sample format is always in native-endian order. 
* Sample values can be expressed by native C types, hence the lack of a signed 
* 24-bit sample format even though it is a common raw audio data format. 
* 
* @par 
* The floating-point formats are based on full volume being in the range 
* [-1.0, 1.0]. Any values outside this range are beyond full volume level. 
* 
* @par 
* The data layout as used in av_samples_fill_arrays() and elsewhere in Libav 
* (such as AVFrame in libavcodec) is as follows: 
* 
* @par 
* For planar sample formats, each audio channel is in a separate data plane, 
* and linesize is the buffer size, in bytes, for a single plane. All data 
* planes must be the same size. For packed sample formats, only the first data 
* plane is used, and samples for each channel are interleaved. In this case, 
* linesize is the buffer size, in bytes, for the 1 plane. 
*/ 
enum AVSampleFormat { 
    AV_SAMPLE_FMT_NONE = -1, 
    AV_SAMPLE_FMT_U8,   ///< unsigned 8 bits 
    AV_SAMPLE_FMT_S16,   ///< signed 16 bits 
    AV_SAMPLE_FMT_S32,   ///< signed 32 bits 
    AV_SAMPLE_FMT_FLT,   ///< float 
    AV_SAMPLE_FMT_DBL,   ///< double 

    AV_SAMPLE_FMT_U8P,   ///< unsigned 8 bits, planar 
    AV_SAMPLE_FMT_S16P,  ///< signed 16 bits, planar 
    AV_SAMPLE_FMT_S32P,  ///< signed 32 bits, planar 
    AV_SAMPLE_FMT_FLTP,  ///< float, planar 
    AV_SAMPLE_FMT_DBLP,  ///< double, planar 

    AV_SAMPLE_FMT_NB   ///< Number of sample formats. DO NOT USE if linking dynamically 
}; 

Он специально упоминает, что 24-разрядное отсутствует, хотя это общее сырье формат аудиоданных. Итак, если я использовал libav/ffmpeg для экспорта в аудиофайл, как бы использовать 24-битный звук?

Экспорт аудиофайла выглядит примерно так:

AVCodec *codec = get_codec(); 
AVOutputFormat *oformat = get_output_format(); 
AVFormatContext *fmt_ctx = avformat_alloc_context(); 
assert(fmt_ctx); 
int err = avio_open(&fmt_ctx->pb, get_output_filename(), AVIO_FLAG_WRITE); 
assert(err >= 0); 
fmt_ctx->oformat = oformat; 
AVStream *stream = avformat_new_stream(fmt_ctx, codec); 
assert(stream); 
AVCodecContext *codec_ctx = stream->codec; 
codec_ctx->bit_rate = get_export_bit_rate(); 

// How to set this to 24 bit instead of 32? 
codec_ctx->sample_fmt = AV_SAMPLE_FMT_S32; 

codec_ctx->sample_rate = get_sample_rate(); 
codec_ctx->channel_layout = get_channel_layout() 
codec_ctx->channels = get_channel_count(); 
codec_ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; 

ответ

3

Используйте AV_SAMPLE_FMT_S32 и установить ctx-> bits_per_raw_sample 24. Звук должен быть в СЗБ в 32-разрядное целое число, то, то есть. заполненный 0 в конце.

+0

Почему бы не быть LSB? Тогда 3-байтовое значение будет равно 4-байтовому значению. – andrewrk

+0

Потому что тогда это был бы другой формат. Таким образом, вы можете рассматривать его так же, как 32-битный, что упрощает процесс. – Hendrik

+0

Также, как бы вы определили, поддерживает ли кодек 24-битный звук? – andrewrk