📄 flacenc.c
字号:
if(smp[i] != smp[0]) break; } if(i == n) { sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT; res[0] = smp[0]; return sub->obits; } /* VERBATIM */ if(n < 5) { sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM; encode_residual_verbatim(res, smp, n); return sub->obits * n; } min_order = ctx->options.min_prediction_order; max_order = ctx->options.max_prediction_order; min_porder = ctx->options.min_partition_order; max_porder = ctx->options.max_partition_order; precision = ctx->options.lpc_coeff_precision; omethod = ctx->options.prediction_order_method; /* FIXED */ if(!ctx->options.use_lpc || max_order == 0 || (n <= max_order)) { uint32_t bits[MAX_FIXED_ORDER+1]; if(max_order > MAX_FIXED_ORDER) max_order = MAX_FIXED_ORDER; opt_order = 0; bits[0] = UINT32_MAX; for(i=min_order; i<=max_order; i++) { encode_residual_fixed(res, smp, n, i); bits[i] = calc_rice_params_fixed(&sub->rc, min_porder, max_porder, res, n, i, sub->obits); if(bits[i] < bits[opt_order]) { opt_order = i; } } sub->order = opt_order; sub->type = FLAC_SUBFRAME_FIXED; sub->type_code = sub->type | sub->order; if(sub->order != max_order) { encode_residual_fixed(res, smp, n, sub->order); return calc_rice_params_fixed(&sub->rc, min_porder, max_porder, res, n, sub->order, sub->obits); } return bits[sub->order]; } /* LPC */ opt_order = lpc_calc_coefs(ctx, smp, n, max_order, precision, coefs, shift, ctx->options.use_lpc, omethod); if(omethod == ORDER_METHOD_2LEVEL || omethod == ORDER_METHOD_4LEVEL || omethod == ORDER_METHOD_8LEVEL) { int levels = 1 << omethod;#ifdef __CW32__ uint32_t *bits;#else uint32_t bits[levels];#endif int order; int opt_index = levels-1;#ifdef __CW32__ bits = av_malloc(sizeof(uint32_t)*levels);#endif opt_order = max_order-1; bits[opt_index] = UINT32_MAX; for(i=levels-1; i>=0; i--) { order = min_order + (((max_order-min_order+1) * (i+1)) / levels)-1; if(order < 0) order = 0; encode_residual_lpc(res, smp, n, order+1, coefs[order], shift[order]); bits[i] = calc_rice_params_lpc(&sub->rc, min_porder, max_porder, res, n, order+1, sub->obits, precision); if(bits[i] < bits[opt_index]) { opt_index = i; opt_order = order; } } opt_order++;#ifdef __CW32__ av_free(bits);#endif } else if(omethod == ORDER_METHOD_SEARCH) { // brute-force optimal order search uint32_t bits[MAX_LPC_ORDER]; opt_order = 0; bits[0] = UINT32_MAX; for(i=min_order-1; i<max_order; i++) { encode_residual_lpc(res, smp, n, i+1, coefs[i], shift[i]); bits[i] = calc_rice_params_lpc(&sub->rc, min_porder, max_porder, res, n, i+1, sub->obits, precision); if(bits[i] < bits[opt_order]) { opt_order = i; } } opt_order++; } else if(omethod == ORDER_METHOD_LOG) { uint32_t bits[MAX_LPC_ORDER]; int step; opt_order= min_order - 1 + (max_order-min_order)/3; memset(bits, -1, sizeof(bits)); for(step=16 ;step; step>>=1){ int last= opt_order; for(i=last-step; i<=last+step; i+= step){ if(i<min_order-1 || i>=max_order || bits[i] < UINT32_MAX) continue; encode_residual_lpc(res, smp, n, i+1, coefs[i], shift[i]); bits[i] = calc_rice_params_lpc(&sub->rc, min_porder, max_porder, res, n, i+1, sub->obits, precision); if(bits[i] < bits[opt_order]) opt_order= i; } } opt_order++; } sub->order = opt_order; sub->type = FLAC_SUBFRAME_LPC; sub->type_code = sub->type | (sub->order-1); sub->shift = shift[sub->order-1]; for(i=0; i<sub->order; i++) { sub->coefs[i] = coefs[sub->order-1][i]; } encode_residual_lpc(res, smp, n, sub->order, sub->coefs, sub->shift); return calc_rice_params_lpc(&sub->rc, min_porder, max_porder, res, n, sub->order, sub->obits, precision);}static int encode_residual_v(FlacEncodeContext *ctx, int ch){ int i, n; FlacFrame *frame; FlacSubframe *sub; int32_t *res, *smp; frame = &ctx->frame; sub = &frame->subframes[ch]; res = sub->residual; smp = sub->samples; n = frame->blocksize; /* CONSTANT */ for(i=1; i<n; i++) { if(smp[i] != smp[0]) break; } if(i == n) { sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT; res[0] = smp[0]; return sub->obits; } /* VERBATIM */ sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM; encode_residual_verbatim(res, smp, n); return sub->obits * n;}static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n){ int i, best; int32_t lt, rt; uint64_t sum[4]; uint64_t score[4]; int k; /* calculate sum of 2nd order residual for each channel */ sum[0] = sum[1] = sum[2] = sum[3] = 0; for(i=2; i<n; i++) { lt = left_ch[i] - 2*left_ch[i-1] + left_ch[i-2]; rt = right_ch[i] - 2*right_ch[i-1] + right_ch[i-2]; sum[2] += FFABS((lt + rt) >> 1); sum[3] += FFABS(lt - rt); sum[0] += FFABS(lt); sum[1] += FFABS(rt); } /* estimate bit counts */ for(i=0; i<4; i++) { k = find_optimal_param(2*sum[i], n); sum[i] = rice_encode_count(2*sum[i], n, k); } /* calculate score for each mode */ score[0] = sum[0] + sum[1]; score[1] = sum[0] + sum[3]; score[2] = sum[1] + sum[3]; score[3] = sum[2] + sum[3]; /* return mode with lowest score */ best = 0; for(i=1; i<4; i++) { if(score[i] < score[best]) { best = i; } } if(best == 0) { return FLAC_CHMODE_LEFT_RIGHT; } else if(best == 1) { return FLAC_CHMODE_LEFT_SIDE; } else if(best == 2) { return FLAC_CHMODE_RIGHT_SIDE; } else { return FLAC_CHMODE_MID_SIDE; }}/** * Perform stereo channel decorrelation */static void channel_decorrelation(FlacEncodeContext *ctx){ FlacFrame *frame; int32_t *left, *right; int i, n; frame = &ctx->frame; n = frame->blocksize; left = frame->subframes[0].samples; right = frame->subframes[1].samples; if(ctx->channels != 2) { frame->ch_mode = FLAC_CHMODE_NOT_STEREO; return; } frame->ch_mode = estimate_stereo_mode(left, right, n); /* perform decorrelation and adjust bits-per-sample */ if(frame->ch_mode == FLAC_CHMODE_LEFT_RIGHT) { return; } if(frame->ch_mode == FLAC_CHMODE_MID_SIDE) { int32_t tmp; for(i=0; i<n; i++) { tmp = left[i]; left[i] = (tmp + right[i]) >> 1; right[i] = tmp - right[i]; } frame->subframes[1].obits++; } else if(frame->ch_mode == FLAC_CHMODE_LEFT_SIDE) { for(i=0; i<n; i++) { right[i] = left[i] - right[i]; } frame->subframes[1].obits++; } else { for(i=0; i<n; i++) { left[i] -= right[i]; } frame->subframes[0].obits++; }}static void write_utf8(PutBitContext *pb, uint32_t val){ uint8_t tmp; PUT_UTF8(val, tmp, put_bits(pb, 8, tmp);)}static void output_frame_header(FlacEncodeContext *s){ FlacFrame *frame; int crc; frame = &s->frame; put_bits(&s->pb, 16, 0xFFF8); put_bits(&s->pb, 4, frame->bs_code[0]); put_bits(&s->pb, 4, s->sr_code[0]); if(frame->ch_mode == FLAC_CHMODE_NOT_STEREO) { put_bits(&s->pb, 4, s->ch_code); } else { put_bits(&s->pb, 4, frame->ch_mode); } put_bits(&s->pb, 3, 4); /* bits-per-sample code */ put_bits(&s->pb, 1, 0); write_utf8(&s->pb, s->frame_count); if(frame->bs_code[0] == 6) { put_bits(&s->pb, 8, frame->bs_code[1]); } else if(frame->bs_code[0] == 7) { put_bits(&s->pb, 16, frame->bs_code[1]); } if(s->sr_code[0] == 12) { put_bits(&s->pb, 8, s->sr_code[1]); } else if(s->sr_code[0] > 12) { put_bits(&s->pb, 16, s->sr_code[1]); } flush_put_bits(&s->pb); crc = av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, s->pb.buf, put_bits_count(&s->pb)>>3); put_bits(&s->pb, 8, crc);}static void output_subframe_constant(FlacEncodeContext *s, int ch){ FlacSubframe *sub; int32_t res; sub = &s->frame.subframes[ch]; res = sub->residual[0]; put_sbits(&s->pb, sub->obits, res);}static void output_subframe_verbatim(FlacEncodeContext *s, int ch){ int i; FlacFrame *frame; FlacSubframe *sub; int32_t res; frame = &s->frame; sub = &frame->subframes[ch]; for(i=0; i<frame->blocksize; i++) { res = sub->residual[i]; put_sbits(&s->pb, sub->obits, res); }}static void output_residual(FlacEncodeContext *ctx, int ch){ int i, j, p, n, parts; int k, porder, psize, res_cnt; FlacFrame *frame; FlacSubframe *sub; int32_t *res; frame = &ctx->frame; sub = &frame->subframes[ch]; res = sub->residual; n = frame->blocksize; /* rice-encoded block */ put_bits(&ctx->pb, 2, 0); /* partition order */ porder = sub->rc.porder; psize = n >> porder; parts = (1 << porder); put_bits(&ctx->pb, 4, porder); res_cnt = psize - sub->order; /* residual */ j = sub->order; for(p=0; p<parts; p++) { k = sub->rc.params[p]; put_bits(&ctx->pb, 4, k); if(p == 1) res_cnt = psize; for(i=0; i<res_cnt && j<n; i++, j++) { set_sr_golomb_flac(&ctx->pb, res[j], k, INT32_MAX, 0); } }}static void output_subframe_fixed(FlacEncodeContext *ctx, int ch){ int i; FlacFrame *frame; FlacSubframe *sub; frame = &ctx->frame; sub = &frame->subframes[ch]; /* warm-up samples */ for(i=0; i<sub->order; i++) { put_sbits(&ctx->pb, sub->obits, sub->residual[i]); } /* residual */ output_residual(ctx, ch);}static void output_subframe_lpc(FlacEncodeContext *ctx, int ch){ int i, cbits; FlacFrame *frame; FlacSubframe *sub; frame = &ctx->frame; sub = &frame->subframes[ch]; /* warm-up samples */ for(i=0; i<sub->order; i++) { put_sbits(&ctx->pb, sub->obits, sub->residual[i]); } /* LPC coefficients */ cbits = ctx->options.lpc_coeff_precision; put_bits(&ctx->pb, 4, cbits-1); put_sbits(&ctx->pb, 5, sub->shift); for(i=0; i<sub->order; i++) { put_sbits(&ctx->pb, cbits, sub->coefs[i]); } /* residual */ output_residual(ctx, ch);}static void output_subframes(FlacEncodeContext *s){ FlacFrame *frame; FlacSubframe *sub; int ch; frame = &s->frame; for(ch=0; ch<s->channels; ch++) { sub = &frame->subframes[ch]; /* subframe header */ put_bits(&s->pb, 1, 0); put_bits(&s->pb, 6, sub->type_code); put_bits(&s->pb, 1, 0); /* no wasted bits */ /* subframe */ if(sub->type == FLAC_SUBFRAME_CONSTANT) { output_subframe_constant(s, ch); } else if(sub->type == FLAC_SUBFRAME_VERBATIM) { output_subframe_verbatim(s, ch); } else if(sub->type == FLAC_SUBFRAME_FIXED) { output_subframe_fixed(s, ch); } else if(sub->type == FLAC_SUBFRAME_LPC) { output_subframe_lpc(s, ch); } }}static void output_frame_footer(FlacEncodeContext *s){ int crc; flush_put_bits(&s->pb); crc = bswap_16(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, s->pb.buf, put_bits_count(&s->pb)>>3)); put_bits(&s->pb, 16, crc); flush_put_bits(&s->pb);}static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size, void *data){ int ch; FlacEncodeContext *s; int16_t *samples = data; int out_bytes; s = avctx->priv_data; init_frame(s); copy_samples(s, samples); channel_decorrelation(s); for(ch=0; ch<s->channels; ch++) { encode_residual(s, ch); } init_put_bits(&s->pb, frame, buf_size); output_frame_header(s); output_subframes(s); output_frame_footer(s); out_bytes = put_bits_count(&s->pb) >> 3; if(out_bytes > s->max_framesize || out_bytes >= buf_size) { /* frame too large. use verbatim mode */ for(ch=0; ch<s->channels; ch++) { encode_residual_v(s, ch); } init_put_bits(&s->pb, frame, buf_size); output_frame_header(s); output_subframes(s); output_frame_footer(s); out_bytes = put_bits_count(&s->pb) >> 3; if(out_bytes > s->max_framesize || out_bytes >= buf_size) { /* still too large. must be an error. */ av_log(avctx, AV_LOG_ERROR, "error encoding frame\n"); return -1; } } s->frame_count++; return out_bytes;}static av_cold int flac_encode_close(AVCodecContext *avctx){ av_freep(&avctx->extradata); avctx->extradata_size = 0; av_freep(&avctx->coded_frame); return 0;}AVCodec flac_encoder = { "flac", CODEC_TYPE_AUDIO, CODEC_ID_FLAC, sizeof(FlacEncodeContext), flac_encode_init, flac_encode_frame, flac_encode_close, NULL,#ifdef __CW32__ CODEC_CAP_SMALL_LAST_FRAME, 0, 0, 0, 0, NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),#else .capabilities = CODEC_CAP_SMALL_LAST_FRAME, .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),#endif};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -