On Tue, Aug 23, 2016 at 02:33:00AM +0530, Jai Luthra wrote: > * Multichannel support for TrueHD is experimental > > There should be downmix substreams present for 2+ channel bitstreams, > but ffmpeg decoder doesn't need it. Will add support for this soon. > > * There might be lossless check failures on LFE channels > > * 32-bit sample support has been removed for now, will add it later > > While testing, some samples gave lossless check failures when enforcing > s32. Probably this will also get solved with other lossless issues. > > Signed-off-by: Jai Luthra <m...@jailuthra.in> > --- > libavcodec/Makefile | 2 + > libavcodec/allcodecs.c | 4 +- > libavcodec/mlp.c | 21 + > libavcodec/mlp.h | 40 + > libavcodec/mlpenc.c | 2416 > ++++++++++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 2481 insertions(+), 2 deletions(-) > create mode 100644 libavcodec/mlpenc.c [...]
> +static av_cold int mlp_encode_init(AVCodecContext *avctx) > +{ > + MLPEncodeContext *ctx = avctx->priv_data; > + unsigned int substr, index; > + unsigned int sum = 0; > + unsigned int size; > + > + ctx->avctx = avctx; > + > + switch (avctx->sample_rate) { > + case 44100 << 0: > + avctx->frame_size = 40 << 0; > + ctx->coded_sample_rate[0] = 0x08 + 0; > + ctx->fs = 0x08 + 1; > + break; > + case 44100 << 1: > + avctx->frame_size = 40 << 1; > + ctx->coded_sample_rate[0] = 0x08 + 1; > + ctx->fs = 0x0C + 1; > + break; > + case 44100 << 2: > + ctx->substream_info |= SUBSTREAM_INFO_HIGH_RATE; > + avctx->frame_size = 40 << 2; > + ctx->coded_sample_rate[0] = 0x08 + 2; > + ctx->fs = 0x10 + 1; > + break; > + case 48000 << 0: > + avctx->frame_size = 40 << 0; > + ctx->coded_sample_rate[0] = 0x00 + 0; > + ctx->fs = 0x08 + 2; > + break; > + case 48000 << 1: > + avctx->frame_size = 40 << 1; > + ctx->coded_sample_rate[0] = 0x00 + 1; > + ctx->fs = 0x0C + 2; > + break; > + case 48000 << 2: > + ctx->substream_info |= SUBSTREAM_INFO_HIGH_RATE; > + avctx->frame_size = 40 << 2; > + ctx->coded_sample_rate[0] = 0x00 + 2; > + ctx->fs = 0x10 + 2; > + break; > + default: > + 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; > + } > + ctx->coded_sample_rate[1] = -1 & 0xf; > + > + /* TODO Keep count of bitrate and calculate real value. */ > + ctx->coded_peak_bitrate = mlp_peak_bitrate(9600000, avctx->sample_rate); > + > + /* TODO support more channels. */ > + if (avctx->channels > 2) { > + av_log(avctx, AV_LOG_WARNING, > + "Only mono and stereo are supported at the moment.\n"); > + } > + > + ctx->substream_info |= SUBSTREAM_INFO_ALWAYS_SET; > + if (avctx->channels <= 2) { > + ctx->substream_info |= SUBSTREAM_INFO_MAX_2_CHAN; > + } > + > + switch (avctx->sample_fmt) { > + case AV_SAMPLE_FMT_S16: > + ctx->coded_sample_fmt[0] = BITS_16; > + ctx->wordlength = 16; > + avctx->bits_per_raw_sample = 16; > + break; > + /* TODO 20 bits: */ > + case AV_SAMPLE_FMT_S32: > + ctx->coded_sample_fmt[0] = BITS_24; > + ctx->wordlength = 24; > + avctx->bits_per_raw_sample = 24; > + break; > + default: > + av_log(avctx, AV_LOG_ERROR, "Sample format not supported. " > + "Only 16- and 24-bit samples are supported.\n"); > + return -1; > + } > + ctx->coded_sample_fmt[1] = -1 & 0xf; > + > + ctx->dts = -avctx->frame_size; > + > + ctx->num_channels = avctx->channels + 2; /* +2 noise channels */ > + ctx->one_sample_buffer_size = avctx->frame_size > + * ctx->num_channels; > + /* TODO Let user pass major header interval as parameter. */ > + ctx->max_restart_interval = MAJOR_HEADER_INTERVAL; > + > + ctx->max_codebook_search = 3; > + ctx->min_restart_interval = MAJOR_HEADER_INTERVAL; > + ctx->restart_intervals = ctx->max_restart_interval / > ctx->min_restart_interval; > + > + /* TODO Let user pass parameters for LPC filter. */ > + > + size = sizeof(int32_t) * avctx->frame_size * ctx->max_restart_interval; > + > + ctx->lpc_sample_buffer = av_malloc(size); av_malloc_array() > + if (!ctx->lpc_sample_buffer) { > + av_log(avctx, AV_LOG_ERROR, > + "Not enough memory for buffering samples.\n"); > + return -1; AVERROR(ENOMEM) > + } > + > + size = sizeof(int32_t) > + * ctx->one_sample_buffer_size * ctx->max_restart_interval; > + > + ctx->major_scratch_buffer = av_malloc(size); > + if (!ctx->major_scratch_buffer) { > + av_log(avctx, AV_LOG_ERROR, > + "Not enough memory for buffering samples.\n"); > + return -1; > + } > + > + ctx->major_inout_buffer = av_malloc(size); > + if (!ctx->major_inout_buffer) { > + av_log(avctx, AV_LOG_ERROR, > + "Not enough memory for buffering samples.\n"); > + return -1; > + } > + > + ff_mlp_init_crc(); > + > + ctx->num_substreams = 1; // TODO: change this after adding multi-channel > support for TrueHD > + > + if (ctx->avctx->codec_id == AV_CODEC_ID_MLP) { > + /* MLP */ > + switch(avctx->channel_layout) { > + case AV_CH_LAYOUT_MONO: > + ctx->channel_arrangement = 0; break; > + case AV_CH_LAYOUT_STEREO: > + ctx->channel_arrangement = 1; break; > + case AV_CH_LAYOUT_2_1: > + ctx->channel_arrangement = 2; break; > + case AV_CH_LAYOUT_QUAD: > + ctx->channel_arrangement = 3; break; > + case AV_CH_LAYOUT_2POINT1: > + ctx->channel_arrangement = 4; break; > + case AV_CH_LAYOUT_SURROUND: > + ctx->channel_arrangement = 7; break; > + case AV_CH_LAYOUT_4POINT0: > + ctx->channel_arrangement = 8; break; > + case AV_CH_LAYOUT_5POINT0_BACK: > + ctx->channel_arrangement = 9; break; > + case AV_CH_LAYOUT_3POINT1: > + ctx->channel_arrangement = 10; break; > + case AV_CH_LAYOUT_4POINT1: > + ctx->channel_arrangement = 11; break; > + case AV_CH_LAYOUT_5POINT1_BACK: > + ctx->channel_arrangement = 12; break; > + default: > + av_log(avctx, AV_LOG_ERROR, "Unsupported channel arrangement\n"); > + return -1; > + } > + ctx->flags = FLAGS_DVDA; > + ctx->channel_occupancy = > ff_mlp_ch_info[ctx->channel_arrangement].channel_occupancy; > + ctx->summary_info = > ff_mlp_ch_info[ctx->channel_arrangement].summary_info ; > + } else { > + /* TrueHD */ > + switch(avctx->channel_layout) { > + case AV_CH_LAYOUT_STEREO: > + ctx->ch_modifier_thd0 = 0; > + ctx->ch_modifier_thd1 = 0; > + ctx->ch_modifier_thd2 = 0; > + ctx->channel_arrangement = 1; > + break; > + case AV_CH_LAYOUT_5POINT0_BACK: > + ctx->ch_modifier_thd0 = 1; > + ctx->ch_modifier_thd1 = 1; > + ctx->ch_modifier_thd2 = 1; > + ctx->channel_arrangement = 11; > + break; > + case AV_CH_LAYOUT_5POINT1_BACK: > + ctx->ch_modifier_thd0 = 2; > + ctx->ch_modifier_thd1 = 1; > + ctx->ch_modifier_thd2 = 2; > + ctx->channel_arrangement = 15; > + break; > + default: > + av_log(avctx, AV_LOG_ERROR, "Unsupported channel arrangement\n"); > + return -1; > + } > + ctx->flags = 0; > + ctx->channel_occupancy = 0; > + ctx->summary_info = 0; > + } > + > + size = sizeof(unsigned int) * ctx->max_restart_interval; > + > + ctx->frame_size = av_malloc(size); > + if (!ctx->frame_size) > + return -1; > + > + ctx->max_output_bits = av_malloc(size); > + if (!ctx->max_output_bits) > + return -1; > + > + size = sizeof(int32_t) > + * ctx->num_substreams * ctx->max_restart_interval; > + > + ctx->lossless_check_data = av_malloc(size); > + if (!ctx->lossless_check_data) > + return -1; > + > + for (index = 0; index < ctx->restart_intervals; index++) { > + ctx->seq_offset[index] = sum; > + ctx->seq_size [index] = ((index + 1) * ctx->min_restart_interval) + > 1; > + sum += ctx->seq_size[index]; > + } > + ctx->sequence_size = sum; > + size = sizeof(ChannelParams) > + * ctx->restart_intervals * ctx->sequence_size * > ctx->avctx->channels; > + ctx->channel_params = av_malloc(size); > + if (!ctx->channel_params) { > + av_log(avctx, AV_LOG_ERROR, > + "Not enough memory for analysis context.\n"); > + return -1; > + } > + > + size = sizeof(DecodingParams) > + * ctx->restart_intervals * ctx->sequence_size * ctx->num_substreams; > + ctx->decoding_params = av_malloc(size); > + if (!ctx->decoding_params) { > + av_log(avctx, AV_LOG_ERROR, > + "Not enough memory for analysis context.\n"); > + return -1; > + } > + > + for (substr = 0; substr < ctx->num_substreams; substr++) { > + RestartHeader *rh = &ctx->restart_header [substr]; > + > + /* TODO see if noisegen_seed is really worth it. */ > + rh->noisegen_seed = 0; > + > + rh->min_channel = 0; > + rh->max_channel = avctx->channels - 1; > + /* FIXME: this works for 1 and 2 channels, but check for more */ > + rh->max_matrix_channel = rh->max_channel; > + } > + > + clear_channel_params(ctx, restart_channel_params); > + clear_decoding_params(ctx, restart_decoding_params); > + > + if (ff_lpc_init(&ctx->lpc_ctx, ctx->number_of_samples, > + MLP_MAX_LPC_ORDER, FF_LPC_TYPE_LEVINSON) < 0) { > + av_log(avctx, AV_LOG_ERROR, > + "Not enough memory for LPC context.\n"); > + return -1; the error code from ff_lpc_init() should be returned a fate test could also be added no more comments from me thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB If you think the mosad wants you dead since a long time then you are either wrong or dead since a long time.
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel