📄 alac.c
字号:
while (predictor_num >= 0 && error_val > 0) { int val = buffer_out[0] - buffer_out[predictor_coef_num - predictor_num]; int sign = sign_only(val); predictor_coef_table[predictor_num] -= sign; val *= sign; /* absolute value */ error_val -= ((val >> predictor_quantitization) * (predictor_coef_num - predictor_num)); predictor_num--; } } else if (error_val < 0) { int predictor_num = predictor_coef_num - 1; while (predictor_num >= 0 && error_val < 0) { int val = buffer_out[0] - buffer_out[predictor_coef_num - predictor_num]; int sign = - sign_only(val); predictor_coef_table[predictor_num] -= sign; val *= sign; /* neg value */ error_val -= ((val >> predictor_quantitization) * (predictor_coef_num - predictor_num)); predictor_num--; } } buffer_out++; } }}static void reconstruct_stereo_16(int32_t *buffer[MAX_CHANNELS], int16_t *buffer_out, int numchannels, int numsamples, uint8_t interlacing_shift, uint8_t interlacing_leftweight){ int i; if (numsamples <= 0) return; /* weighted interlacing */ if (interlacing_leftweight) { for (i = 0; i < numsamples; i++) { int32_t a, b; a = buffer[0][i]; b = buffer[1][i]; a -= (b * interlacing_leftweight) >> interlacing_shift; b += a; buffer_out[i*numchannels] = b; buffer_out[i*numchannels + 1] = a; } return; } /* otherwise basic interlacing took place */ for (i = 0; i < numsamples; i++) { int16_t left, right; left = buffer[0][i]; right = buffer[1][i]; buffer_out[i*numchannels] = left; buffer_out[i*numchannels + 1] = right; }}static int alac_decode_frame(AVCodecContext *avctx, void *outbuffer, int *outputsize, const uint8_t *inbuffer, int input_buffer_size){ ALACContext *alac = avctx->priv_data; int channels; unsigned int outputsamples; int hassize; int readsamplesize; int wasted_bytes; int isnotcompressed; uint8_t interlacing_shift; uint8_t interlacing_leftweight; /* short-circuit null buffers */ if (!inbuffer || !input_buffer_size) return input_buffer_size; /* initialize from the extradata */ if (!alac->context_initialized) { if (alac->avctx->extradata_size != ALAC_EXTRADATA_SIZE) { av_log(avctx, AV_LOG_ERROR, "alac: expected %d extradata bytes\n", ALAC_EXTRADATA_SIZE); return input_buffer_size; } if (alac_set_info(alac)) { av_log(avctx, AV_LOG_ERROR, "alac: set_info failed\n"); return input_buffer_size; } alac->context_initialized = 1; } init_get_bits(&alac->gb, inbuffer, input_buffer_size * 8); channels = get_bits(&alac->gb, 3) + 1; if (channels > MAX_CHANNELS) { av_log(avctx, AV_LOG_ERROR, "channels > %d not supported\n", MAX_CHANNELS); return input_buffer_size; } /* 2^result = something to do with output waiting. * perhaps matters if we read > 1 frame in a pass? */ skip_bits(&alac->gb, 4); skip_bits(&alac->gb, 12); /* unknown, skip 12 bits */ /* the output sample size is stored soon */ hassize = get_bits1(&alac->gb); wasted_bytes = get_bits(&alac->gb, 2); /* unknown ? */ /* whether the frame is compressed */ isnotcompressed = get_bits1(&alac->gb); if (hassize) { /* now read the number of samples as a 32bit integer */ outputsamples = get_bits_long(&alac->gb, 32); if(outputsamples > alac->setinfo_max_samples_per_frame){ av_log(avctx, AV_LOG_ERROR, "outputsamples %d > %d\n", outputsamples, alac->setinfo_max_samples_per_frame); return -1; } } else outputsamples = alac->setinfo_max_samples_per_frame; if(outputsamples > *outputsize / alac->bytespersample){ av_log(avctx, AV_LOG_ERROR, "sample buffer too small\n"); return -1; } *outputsize = outputsamples * alac->bytespersample; readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8) + channels - 1; if (!isnotcompressed) { /* so it is compressed */#ifndef __CW32__ int16_t predictor_coef_table[channels][32]; int predictor_coef_num[channels]; int prediction_type[channels]; int prediction_quantitization[channels]; int ricemodifier[channels]; int i, chan;#else int16_t **predictor_coef_table; int *predictor_coef_num; int *prediction_type; int *prediction_quantitization; int *ricemodifier; int i, chan; predictor_coef_table = av_malloc(sizeof(int16_t)*channels*32); predictor_coef_num = av_malloc(sizeof(int)*channels); prediction_type = av_malloc(sizeof(int)*channels); prediction_quantitization = av_malloc(sizeof(int)*channels); ricemodifier = av_malloc(sizeof(int)*channels);#endif interlacing_shift = get_bits(&alac->gb, 8); interlacing_leftweight = get_bits(&alac->gb, 8); for (chan = 0; chan < channels; chan++) { prediction_type[chan] = get_bits(&alac->gb, 4); prediction_quantitization[chan] = get_bits(&alac->gb, 4); ricemodifier[chan] = get_bits(&alac->gb, 3); predictor_coef_num[chan] = get_bits(&alac->gb, 5); /* read the predictor table */ for (i = 0; i < predictor_coef_num[chan]; i++) predictor_coef_table[chan][i] = (int16_t)get_bits(&alac->gb, 16); } if (wasted_bytes) av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented, unhandling of wasted_bytes\n"); for (chan = 0; chan < channels; chan++) { bastardized_rice_decompress(alac, alac->predicterror_buffer[chan], outputsamples, readsamplesize, alac->setinfo_rice_initialhistory, alac->setinfo_rice_kmodifier, ricemodifier[chan] * alac->setinfo_rice_historymult / 4, (1 << alac->setinfo_rice_kmodifier) - 1); if (prediction_type[chan] == 0) { /* adaptive fir */ predictor_decompress_fir_adapt(alac->predicterror_buffer[chan], alac->outputsamples_buffer[chan], outputsamples, readsamplesize, predictor_coef_table[chan], predictor_coef_num[chan], prediction_quantitization[chan]); } else { av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type[chan]); /* I think the only other prediction type (or perhaps this is * just a boolean?) runs adaptive fir twice.. like: * predictor_decompress_fir_adapt(predictor_error, tempout, ...) * predictor_decompress_fir_adapt(predictor_error, outputsamples ...) * little strange.. */ } }#ifdef __CW32__ av_free(predictor_coef_table); av_free(predictor_coef_num); av_free(prediction_type); av_free(prediction_quantitization); av_free(ricemodifier);#endif } else { /* not compressed, easy case */ int i, chan; for (i = 0; i < outputsamples; i++) for (chan = 0; chan < channels; chan++) { int32_t audiobits; audiobits = get_bits_long(&alac->gb, alac->setinfo_sample_size); audiobits = extend_sign32(audiobits, alac->setinfo_sample_size); alac->outputsamples_buffer[chan][i] = audiobits; } /* wasted_bytes = 0; */ interlacing_shift = 0; interlacing_leftweight = 0; } if (get_bits(&alac->gb, 3) != 7) av_log(avctx, AV_LOG_ERROR, "Error : Wrong End Of Frame\n"); switch(alac->setinfo_sample_size) { case 16: if (channels == 2) { reconstruct_stereo_16(alac->outputsamples_buffer, (int16_t*)outbuffer, alac->numchannels, outputsamples, interlacing_shift, interlacing_leftweight); } else { int i; for (i = 0; i < outputsamples; i++) { int16_t sample = alac->outputsamples_buffer[0][i]; ((int16_t*)outbuffer)[i * alac->numchannels] = sample; } } break; case 20: case 24: // It is not clear if there exist any encoder that creates 24 bit ALAC // files. iTunes convert 24 bit raw files to 16 bit before encoding. case 32: av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size); break; default: break; } if (input_buffer_size * 8 - get_bits_count(&alac->gb) > 8) av_log(avctx, AV_LOG_ERROR, "Error : %d bits left\n", input_buffer_size * 8 - get_bits_count(&alac->gb)); return input_buffer_size;}static av_cold int alac_decode_init(AVCodecContext * avctx){ ALACContext *alac = avctx->priv_data; alac->avctx = avctx; alac->context_initialized = 0; alac->numchannels = alac->avctx->channels; alac->bytespersample = (avctx->bits_per_sample / 8) * alac->numchannels; return 0;}static av_cold int alac_decode_close(AVCodecContext *avctx){ ALACContext *alac = avctx->priv_data; int chan; for (chan = 0; chan < MAX_CHANNELS; chan++) { av_free(alac->predicterror_buffer[chan]); av_free(alac->outputsamples_buffer[chan]); } return 0;}AVCodec alac_decoder = { "alac", CODEC_TYPE_AUDIO, CODEC_ID_ALAC, sizeof(ALACContext), alac_decode_init, NULL, alac_decode_close, alac_decode_frame,#ifdef __CW32__ 0, 0, 0, 0, 0, NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),#else .long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),#endif};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -