|
|
|
@ -462,14 +462,15 @@ static int write_frame(AlacEncodeContext *s, AVPacket *avpkt, |
|
|
|
|
uint8_t * const *samples) |
|
|
|
|
{ |
|
|
|
|
PutBitContext *pb = &s->pbctx; |
|
|
|
|
const enum AlacRawDataBlockType *ch_elements = ff_alac_channel_elements[s->avctx->channels - 1]; |
|
|
|
|
const uint8_t *ch_map = ff_alac_channel_layout_offsets[s->avctx->channels - 1]; |
|
|
|
|
int channels = s->avctx->ch_layout.nb_channels; |
|
|
|
|
const enum AlacRawDataBlockType *ch_elements = ff_alac_channel_elements[channels - 1]; |
|
|
|
|
const uint8_t *ch_map = ff_alac_channel_layout_offsets[channels - 1]; |
|
|
|
|
int ch, element, sce, cpe; |
|
|
|
|
|
|
|
|
|
init_put_bits(pb, avpkt->data, avpkt->size); |
|
|
|
|
|
|
|
|
|
ch = element = sce = cpe = 0; |
|
|
|
|
while (ch < s->avctx->channels) { |
|
|
|
|
while (ch < channels) { |
|
|
|
|
if (ch_elements[element] == TYPE_CPE) { |
|
|
|
|
write_element(s, TYPE_CPE, cpe, samples[ch_map[ch]], |
|
|
|
|
samples[ch_map[ch + 1]]); |
|
|
|
@ -532,7 +533,7 @@ static av_cold int alac_encode_init(AVCodecContext *avctx) |
|
|
|
|
s->rc.rice_modifier = 4; |
|
|
|
|
|
|
|
|
|
s->max_coded_frame_size = get_max_frame_size(avctx->frame_size, |
|
|
|
|
avctx->channels, |
|
|
|
|
avctx->ch_layout.nb_channels, |
|
|
|
|
avctx->bits_per_raw_sample); |
|
|
|
|
|
|
|
|
|
avctx->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE); |
|
|
|
@ -545,10 +546,10 @@ static av_cold int alac_encode_init(AVCodecContext *avctx) |
|
|
|
|
AV_WB32(alac_extradata+4, MKBETAG('a','l','a','c')); |
|
|
|
|
AV_WB32(alac_extradata+12, avctx->frame_size); |
|
|
|
|
AV_WB8 (alac_extradata+17, avctx->bits_per_raw_sample); |
|
|
|
|
AV_WB8 (alac_extradata+21, avctx->channels); |
|
|
|
|
AV_WB8 (alac_extradata+21, avctx->ch_layout.nb_channels); |
|
|
|
|
AV_WB32(alac_extradata+24, s->max_coded_frame_size); |
|
|
|
|
AV_WB32(alac_extradata+28, |
|
|
|
|
avctx->sample_rate * avctx->channels * avctx->bits_per_raw_sample); // average bitrate
|
|
|
|
|
avctx->sample_rate * avctx->ch_layout.nb_channels * avctx->bits_per_raw_sample); // average bitrate
|
|
|
|
|
AV_WB32(alac_extradata+32, avctx->sample_rate); |
|
|
|
|
|
|
|
|
|
// Set relevant extradata fields
|
|
|
|
@ -585,7 +586,7 @@ static int alac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, |
|
|
|
|
s->frame_size = frame->nb_samples; |
|
|
|
|
|
|
|
|
|
if (frame->nb_samples < DEFAULT_FRAME_SIZE) |
|
|
|
|
max_frame_size = get_max_frame_size(s->frame_size, avctx->channels, |
|
|
|
|
max_frame_size = get_max_frame_size(s->frame_size, avctx->ch_layout.nb_channels, |
|
|
|
|
avctx->bits_per_raw_sample); |
|
|
|
|
else |
|
|
|
|
max_frame_size = s->max_coded_frame_size; |
|
|
|
@ -616,6 +617,21 @@ static int alac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if FF_API_OLD_CHANNEL_LAYOUT |
|
|
|
|
static const uint64_t alac_channel_layouts[ALAC_MAX_CHANNELS + 1] = { |
|
|
|
|
AV_CH_LAYOUT_MONO, |
|
|
|
|
AV_CH_LAYOUT_STEREO, |
|
|
|
|
AV_CH_LAYOUT_SURROUND, |
|
|
|
|
AV_CH_LAYOUT_4POINT0, |
|
|
|
|
AV_CH_LAYOUT_5POINT0_BACK, |
|
|
|
|
AV_CH_LAYOUT_5POINT1_BACK, |
|
|
|
|
AV_CH_LAYOUT_6POINT1_BACK, |
|
|
|
|
AV_CH_LAYOUT_7POINT1_WIDE_BACK, |
|
|
|
|
0 |
|
|
|
|
}; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define OFFSET(x) offsetof(AlacEncodeContext, x) |
|
|
|
|
#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM |
|
|
|
|
static const AVOption options[] = { |
|
|
|
@ -632,6 +648,7 @@ static const AVClass alacenc_class = { |
|
|
|
|
.version = LIBAVUTIL_VERSION_INT, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
FF_DISABLE_DEPRECATION_WARNINGS |
|
|
|
|
const AVCodec ff_alac_encoder = { |
|
|
|
|
.name = "alac", |
|
|
|
|
.long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"), |
|
|
|
@ -643,9 +660,13 @@ const AVCodec ff_alac_encoder = { |
|
|
|
|
.encode2 = alac_encode_frame, |
|
|
|
|
.close = alac_encode_close, |
|
|
|
|
.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME, |
|
|
|
|
.channel_layouts = ff_alac_channel_layouts, |
|
|
|
|
#if FF_API_OLD_CHANNEL_LAYOUT |
|
|
|
|
.channel_layouts = alac_channel_layouts, |
|
|
|
|
#endif |
|
|
|
|
.ch_layouts = ff_alac_ch_layouts, |
|
|
|
|
.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32P, |
|
|
|
|
AV_SAMPLE_FMT_S16P, |
|
|
|
|
AV_SAMPLE_FMT_NONE }, |
|
|
|
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, |
|
|
|
|
}; |
|
|
|
|
FF_ENABLE_DEPRECATION_WARNINGS |
|
|
|
|