X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmlpenc.c;h=a66965f2bfd4d59e245ee1c8d4e56d46fd34543c;hb=a247ac640df3da573cd661065bf53f37863e2b46;hp=7536d3b2f50949836bd164854d2fae66aaec1257;hpb=94d98330ed6c5562341315c26c1af92771a2e6de;p=ffmpeg diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c index 7536d3b2f50..a66965f2bfd 100644 --- a/libavcodec/mlpenc.c +++ b/libavcodec/mlpenc.c @@ -1,6 +1,7 @@ /** * MLP encoder * Copyright (c) 2008 Ramiro Polla + * Copyright (c) 2016-2019 Jai Luthra * * This file is part of FFmpeg. * @@ -86,15 +87,15 @@ typedef struct { } DecodingParams; typedef struct BestOffset { - int16_t offset; + int32_t offset; int bitcount; int lsb_bits; - int16_t min; - int16_t max; + int32_t min; + int32_t max; } BestOffset; -#define HUFF_OFFSET_MIN -16384 -#define HUFF_OFFSET_MAX 16383 +#define HUFF_OFFSET_MIN (-16384) +#define HUFF_OFFSET_MAX ( 16383) /** Number of possible codebooks (counting "no codebooks") */ #define NUM_CODEBOOKS 4 @@ -466,7 +467,7 @@ static void default_decoding_params(MLPEncodeContext *ctx, */ static int inline number_sbits(int number) { - if (number < 0) + if (number < -1) number++; return av_log2(FFABS(number)) + 1 + !!number; @@ -530,7 +531,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d. Supported " "sample rates are 44100, 88200, 176400, 48000, " "96000, and 192000.\n", avctx->sample_rate); - return -1; + return AVERROR(EINVAL); } ctx->coded_sample_rate[1] = -1 & 0xf; @@ -563,7 +564,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx) default: av_log(avctx, AV_LOG_ERROR, "Sample format not supported. " "Only 16- and 24-bit samples are supported.\n"); - return -1; + return AVERROR(EINVAL); } ctx->coded_sample_fmt[1] = -1 & 0xf; @@ -637,7 +638,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx) ctx->channel_arrangement = 12; break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported channel arrangement\n"); - return -1; + return AVERROR(EINVAL); } ctx->flags = FLAGS_DVDA; ctx->channel_occupancy = ff_mlp_ch_info[ctx->channel_arrangement].channel_occupancy; @@ -665,7 +666,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx) break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported channel arrangement\n"); - return -1; + return AVERROR(EINVAL); } ctx->flags = 0; ctx->channel_occupancy = 0; @@ -807,7 +808,7 @@ static void write_major_sync(MLPEncodeContext *ctx, uint8_t *buf, int buf_size) static void write_restart_header(MLPEncodeContext *ctx, PutBitContext *pb) { RestartHeader *rh = ctx->cur_restart_header; - int32_t lossless_check = xor_32_to_8(rh->lossless_check_data); + uint8_t lossless_check = xor_32_to_8(rh->lossless_check_data); unsigned int start_count = put_bits_count(pb); PutBitContext tmpb; uint8_t checksum; @@ -986,6 +987,9 @@ static void write_decoding_params(MLPEncodeContext *ctx, PutBitContext *pb, put_bits(pb, 1, 0); } } + if (cp->codebook > 0 && cp->huff_lsbs > 24) { + av_log(ctx->avctx, AV_LOG_ERROR, "Invalid Huff LSBs\n"); + } put_bits(pb, 2, cp->codebook ); put_bits(pb, 5, cp->huff_lsbs); @@ -1016,12 +1020,10 @@ static void write_block_data(MLPEncodeContext *ctx, PutBitContext *pb) codebook_index [ch] = cp->codebook - 1; sign_huff_offset[ch] = cp->huff_offset; - sign_shift = lsb_bits[ch] - 1; + sign_shift = lsb_bits[ch] + (cp->codebook ? 2 - cp->codebook : -1); - if (cp->codebook > 0) { + if (cp->codebook > 0) sign_huff_offset[ch] -= 7 << lsb_bits[ch]; - sign_shift += 3 - cp->codebook; - } /* Unsign if needed. */ if (sign_shift >= 0) @@ -1031,7 +1033,6 @@ static void write_block_data(MLPEncodeContext *ctx, PutBitContext *pb) for (i = 0; i < dp->blocksize; i++) { for (ch = rh->min_channel; ch <= rh->max_channel; ch++) { int32_t sample = *sample_buffer++ >> dp->quant_step_size[ch]; - sample -= sign_huff_offset[ch]; if (codebook_index[ch] >= 0) { @@ -1066,7 +1067,7 @@ static uint8_t *write_substrs(MLPEncodeContext *ctx, uint8_t *buf, int buf_size, RestartHeader *rh = &ctx->restart_header [substr]; int substr_restart_frame = restart_frame; uint8_t parity, checksum; - PutBitContext pb, tmpb; + PutBitContext pb; int params_changed; ctx->cur_restart_header = rh; @@ -1116,22 +1117,22 @@ static uint8_t *write_substrs(MLPEncodeContext *ctx, uint8_t *buf, int buf_size, put_bits(&pb, 32, END_OF_STREAM); } - /* Data must be flushed for the checksum and parity to be correct. */ - tmpb = pb; - flush_put_bits(&tmpb); + /* Data must be flushed for the checksum and parity to be correct; + * notice that we already are word-aligned here. */ + flush_put_bits(&pb); - parity = ff_mlp_calculate_parity(buf, put_bits_count(&pb) >> 3) ^ 0xa9; - checksum = ff_mlp_checksum8 (buf, put_bits_count(&pb) >> 3); + parity = ff_mlp_calculate_parity(buf, put_bytes_output(&pb)) ^ 0xa9; + checksum = ff_mlp_checksum8 (buf, put_bytes_output(&pb)); put_bits(&pb, 8, parity ); put_bits(&pb, 8, checksum); flush_put_bits(&pb); - end += put_bits_count(&pb) >> 3; + end += put_bytes_output(&pb); substream_data_len[substr] = end; - buf += put_bits_count(&pb) >> 3; + buf += put_bytes_output(&pb); } ctx->major_cur_subblock_index += ctx->major_filter_state_subblock + 1; @@ -1189,7 +1190,7 @@ static unsigned int write_access_unit(MLPEncodeContext *ctx, uint8_t *buf, int total_length; if (buf_size < 4) - return -1; + return AVERROR(EINVAL); /* Frame header will be written at the end. */ buf += 4; @@ -1197,7 +1198,7 @@ static unsigned int write_access_unit(MLPEncodeContext *ctx, uint8_t *buf, if (restart_frame) { if (buf_size < 28) - return -1; + return AVERROR(EINVAL); write_major_sync(ctx, buf, buf_size); buf += 28; buf_size -= 28; @@ -1251,7 +1252,7 @@ static void input_data_internal(MLPEncodeContext *ctx, const uint8_t *samples, uint32_t abs_sample; int32_t sample; - sample = is24 ? *samples_32++ >> 8 : *samples_16++ << 8; + sample = is24 ? *samples_32++ >> 8 : *samples_16++ * 256; /* TODO Find out if number_sbits can be used for negative values. */ abs_sample = FFABS(sample); @@ -1562,7 +1563,7 @@ static void no_codebook_bits_offset(MLPEncodeContext *ctx, BestOffset *bo) { DecodingParams *dp = ctx->cur_decoding_params; - int32_t unsign; + int32_t unsign = 0; int lsb_bits; min -= offset; @@ -1572,7 +1573,8 @@ static void no_codebook_bits_offset(MLPEncodeContext *ctx, lsb_bits += !!lsb_bits; - unsign = 1 << (lsb_bits - 1); + if (lsb_bits > 0) + unsign = 1 << (lsb_bits - 1); bo->offset = offset; bo->lsb_bits = lsb_bits; @@ -1591,7 +1593,7 @@ static void no_codebook_bits(MLPEncodeContext *ctx, { DecodingParams *dp = ctx->cur_decoding_params; int16_t offset; - int32_t unsign; + int32_t unsign = 0; uint32_t diff; int lsb_bits; @@ -1607,7 +1609,8 @@ static void no_codebook_bits(MLPEncodeContext *ctx, lsb_bits = number_sbits(diff) - 1; - unsign = 1 << (lsb_bits - 1); + if (lsb_bits > 0) + unsign = 1 << (lsb_bits - 1); /* If all samples are the same (lsb_bits == 0), offset must be * adjusted because of sign_shift. */ @@ -1699,7 +1702,7 @@ static inline void codebook_bits(MLPEncodeContext *ctx, offset_min = FFMAX(min, HUFF_OFFSET_MIN); offset_max = FFMIN(max, HUFF_OFFSET_MAX); - for (;;) { + while (offset <= offset_max && offset >= offset_min) { BestOffset temp_bo; codebook_bits_offset(ctx, channel, codebook, @@ -1718,12 +1721,8 @@ static inline void codebook_bits(MLPEncodeContext *ctx, if (direction) { offset = temp_bo.max + 1; - if (offset > offset_max) - break; } else { offset = temp_bo.min - 1; - if (offset < offset_min) - break; } } } @@ -1796,24 +1795,24 @@ static void determine_bits(MLPEncodeContext *ctx) #define SAMPLE_MAX(bitdepth) ((1 << (bitdepth - 1)) - 1) #define SAMPLE_MIN(bitdepth) (~SAMPLE_MAX(bitdepth)) -#define MSB_MASK(bits) (-1u << bits) +#define MSB_MASK(bits) (-(int)(1u << (bits))) /** Applies the filter to the current samples, and saves the residual back * into the samples buffer. If the filter is too bad and overflows the - * maximum amount of bits allowed (16 or 24), the samples buffer is left as is and + * maximum amount of bits allowed (24), the samples buffer is left as is and * the function returns -1. */ static int apply_filter(MLPEncodeContext *ctx, unsigned int channel) { FilterParams *fp[NUM_FILTERS] = { &ctx->cur_channel_params[channel].filter_params[FIR], &ctx->cur_channel_params[channel].filter_params[IIR], }; - int32_t *filter_state_buffer[NUM_FILTERS]; + int32_t *filter_state_buffer[NUM_FILTERS] = { NULL }; int32_t mask = MSB_MASK(ctx->cur_decoding_params->quant_step_size[channel]); int32_t *sample_buffer = ctx->sample_buffer + channel; unsigned int number_of_samples = ctx->number_of_samples; unsigned int filter_shift = fp[FIR]->shift; int filter; - int i; + int i, ret = 0; for (i = 0; i < NUM_FILTERS; i++) { unsigned int size = ctx->number_of_samples; @@ -1821,7 +1820,8 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned int channel) if (!filter_state_buffer[i]) { av_log(ctx->avctx, AV_LOG_ERROR, "Not enough memory for applying filters.\n"); - return -1; + ret = AVERROR(ENOMEM); + goto free_and_return; } } @@ -1836,7 +1836,7 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned int channel) int32_t sample = *sample_buffer; unsigned int order; int64_t accum = 0; - int32_t residual; + int64_t residual; for (filter = 0; filter < NUM_FILTERS; filter++) { int32_t *fcoeff = ctx->cur_channel_params[channel].coeff[filter]; @@ -1848,11 +1848,13 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned int channel) accum >>= filter_shift; residual = sample - (accum & mask); - if (residual < SAMPLE_MIN(ctx->wordlength) || residual > SAMPLE_MAX(ctx->wordlength)) - return -1; + if (residual < SAMPLE_MIN(24) || residual > SAMPLE_MAX(24)) { + ret = AVERROR_INVALIDDATA; + goto free_and_return; + } filter_state_buffer[FIR][i] = sample; - filter_state_buffer[IIR][i] = residual; + filter_state_buffer[IIR][i] = (int32_t) residual; sample_buffer += ctx->num_channels; } @@ -1864,11 +1866,12 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned int channel) sample_buffer += ctx->num_channels; } +free_and_return: for (i = 0; i < NUM_FILTERS; i++) { av_freep(&filter_state_buffer[i]); } - return 0; + return ret; } static void apply_filters(MLPEncodeContext *ctx) @@ -1897,8 +1900,8 @@ static void generate_2_noise_channels(MLPEncodeContext *ctx) for (i = 0; i < ctx->number_of_samples; i++) { uint16_t seed_shr7 = seed >> 7; - *sample_buffer++ = ((int8_t)(seed >> 15)) << rh->noise_shift; - *sample_buffer++ = ((int8_t) seed_shr7) << rh->noise_shift; + *sample_buffer++ = ((int8_t)(seed >> 15)) * (1 << rh->noise_shift); + *sample_buffer++ = ((int8_t) seed_shr7) * (1 << rh->noise_shift); seed = (seed << 16) ^ seed_shr7 ^ (seed_shr7 << 5); @@ -1944,24 +1947,16 @@ static void rematrix_channels(MLPEncodeContext *ctx) ****************************************************************************/ typedef struct { - char path[MAJOR_HEADER_INTERVAL + 3]; + char path[MAJOR_HEADER_INTERVAL + 2]; + int cur_idx; int bitcount; } PathCounter; -static const char *path_counter_codebook[] = { "0", "1", "2", "3", }; - -#define ZERO_PATH '0' #define CODEBOOK_CHANGE_BITS 21 static void clear_path_counter(PathCounter *path_counter) { - unsigned int i; - - for (i = 0; i < NUM_CODEBOOKS + 1; i++) { - path_counter[i].path[0] = ZERO_PATH; - path_counter[i].path[1] = 0x00; - path_counter[i].bitcount = 0; - } + memset(path_counter, 0, (NUM_CODEBOOKS + 1) * sizeof(*path_counter)); } static int compare_best_offset(BestOffset *prev, BestOffset *cur) @@ -1975,18 +1970,11 @@ static int compare_best_offset(BestOffset *prev, BestOffset *cur) static int best_codebook_path_cost(MLPEncodeContext *ctx, unsigned int channel, PathCounter *src, int cur_codebook) { - BestOffset *cur_bo, *prev_bo = restart_best_offset; + int idx = src->cur_idx; + BestOffset *cur_bo = ctx->best_offset[idx][channel], + *prev_bo = idx ? ctx->best_offset[idx - 1][channel] : restart_best_offset; int bitcount = src->bitcount; - char *path = src->path + 1; - int prev_codebook; - int i; - - for (i = 0; path[i]; i++) - prev_bo = ctx->best_offset[i][channel]; - - prev_codebook = path[i - 1] - ZERO_PATH; - - cur_bo = ctx->best_offset[i][channel]; + int prev_codebook = src->path[idx]; bitcount += cur_bo[cur_codebook].bitcount; @@ -2049,7 +2037,8 @@ static void set_best_codebook(MLPEncodeContext *ctx) prev_best_bitcount = temp_bitcount; if (src_path != dst_path) memcpy(dst_path, src_path, sizeof(PathCounter)); - av_strlcat(dst_path->path, path_counter_codebook[codebook], sizeof(dst_path->path)); + if (dst_path->cur_idx < FF_ARRAY_ELEMS(dst_path->path) - 1) + dst_path->path[++dst_path->cur_idx] = codebook; dst_path->bitcount = temp_bitcount; } } @@ -2066,12 +2055,12 @@ static void set_best_codebook(MLPEncodeContext *ctx) for (index = 0; index < ctx->number_of_subblocks; index++) { ChannelParams *cp = ctx->seq_channel_params + index*(ctx->avctx->channels) + channel; - best_codebook = *best_path++ - ZERO_PATH; + best_codebook = *best_path++; cur_bo = &ctx->best_offset[index][channel][best_codebook]; - cp->huff_offset = cur_bo->offset; - cp->huff_lsbs = cur_bo->lsb_bits + dp->quant_step_size[channel]; - cp->codebook = best_codebook; + cp->huff_offset = cur_bo->offset; + cp->huff_lsbs = cur_bo->lsb_bits + dp->quant_step_size[channel]; + cp->codebook = best_codebook; } } } @@ -2199,9 +2188,6 @@ static void process_major_frame(MLPEncodeContext *ctx) ctx->number_of_samples = ctx->major_frame_size; for (substr = 0; substr < ctx->num_substreams; substr++) { - RestartHeader *rh = ctx->cur_restart_header; - unsigned int channel; - ctx->cur_restart_header = &ctx->restart_header[substr]; ctx->cur_decoding_params = &ctx->major_decoding_params[1][substr]; @@ -2210,8 +2196,7 @@ static void process_major_frame(MLPEncodeContext *ctx) generate_2_noise_channels(ctx); rematrix_channels (ctx); - for (channel = rh->min_channel; channel <= rh->max_channel; channel++) - apply_filter(ctx, channel); + apply_filters(ctx); } } @@ -2228,14 +2213,9 @@ static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if ((ret = ff_alloc_packet2(avctx, avpkt, 87500 * avctx->channels, 0)) < 0) return ret; - if (!frame) - return 1; - /* add current frame to queue */ - if (frame) { - if ((ret = ff_af_queue_add(&ctx->afq, frame)) < 0) - return ret; - } + if ((ret = ff_af_queue_add(&ctx->afq, frame)) < 0) + return ret; data = frame->data[0]; @@ -2271,7 +2251,7 @@ static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (ctx->frame_size[ctx->frame_index] > MAX_BLOCKSIZE) { av_log(avctx, AV_LOG_ERROR, "Invalid frame size (%d > %d)\n", ctx->frame_size[ctx->frame_index], MAX_BLOCKSIZE); - return -1; + return AVERROR_INVALIDDATA; } restart_frame = !ctx->frame_index; @@ -2279,7 +2259,7 @@ static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (restart_frame) { set_major_params(ctx); if (ctx->min_restart_interval != ctx->max_restart_interval) - process_major_frame(ctx); + process_major_frame(ctx); } if (ctx->min_restart_interval == ctx->max_restart_interval) @@ -2377,13 +2357,14 @@ static av_cold int mlp_encode_close(AVCodecContext *avctx) av_freep(&ctx->decoding_params); av_freep(&ctx->channel_params); av_freep(&ctx->frame_size); + av_freep(&ctx->max_output_bits); ff_af_queue_close(&ctx->afq); return 0; } #if CONFIG_MLP_ENCODER -AVCodec ff_mlp_encoder = { +const AVCodec ff_mlp_encoder = { .name ="mlp", .long_name = NULL_IF_CONFIG_SMALL("MLP (Meridian Lossless Packing)"), .type = AVMEDIA_TYPE_AUDIO, @@ -2392,14 +2373,15 @@ AVCodec ff_mlp_encoder = { .init = mlp_encode_init, .encode2 = mlp_encode_frame, .close = mlp_encode_close, - .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL, + .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_EXPERIMENTAL, .sample_fmts = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE}, .supported_samplerates = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0}, .channel_layouts = ff_mlp_channel_layouts, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif #if CONFIG_TRUEHD_ENCODER -AVCodec ff_truehd_encoder = { +const AVCodec ff_truehd_encoder = { .name ="truehd", .long_name = NULL_IF_CONFIG_SMALL("TrueHD"), .type = AVMEDIA_TYPE_AUDIO, @@ -2408,9 +2390,10 @@ AVCodec ff_truehd_encoder = { .init = mlp_encode_init, .encode2 = mlp_encode_frame, .close = mlp_encode_close, - .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL, + .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_EXPERIMENTAL, .sample_fmts = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE}, .supported_samplerates = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0}, .channel_layouts = (const uint64_t[]) {AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_5POINT1_BACK, 0}, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif