Hi, I have first added experimental encoder mlpenc.c from https://github.com/ramiropolla/mlpenc an updated changes according to the recent commits in FFmpeg
>From 0fb7dcf1f126bd137e2b2025c5cd6cff4af65801 Mon Sep 17 00:00:00 2001 From: Greeshma Balabhadra <greeshmabalaba...@gmail.com <binti...@gmail.com>> Date: Thu, 31 Oct 2014 06:30:00 +0530 Subject: [PATCH] mlp encoder : validate MLP bitstream diff --git a/ffmpeg/libavcodec/mlpenc.c b/ffmpeg/libavcodec/mlpenc.c index 70cb7d8..26ece64 100644 --- a/ffmpeg/libavcodec/mlpenc.c +++ b/ffmpeg/libavcodec/mlpenc.c @@ -23,13 +23,14 @@ #include "libavutil/crc.h" #include "libavutil/avstring.h" #include "mlp.h" -#include "dsputil.h" +#include " mlpdsp.h" #include "lpc.h" #define MAJOR_HEADER_INTERVAL 16 #define MLP_MIN_LPC_ORDER 1 #define MLP_MAX_LPC_ORDER 8 #define MLP_MIN_LPC_SHIFT 8 #define MLP_MAX_LPC_SHIFT 15 +#define FF_LPC_TYPE_DEFAULT -1 typedef struct { uint8_t min_channel; ///< The index of the first channel coded in this substream. uint8_t max_channel; ///< The index of the last channel coded in this substream. @@ -141,7 +142,7 @@ DecodingParams *prev_decoding_params; ChannelParams *seq_channel_params; DecodingParams *seq_decoding_params; unsigned int max_codebook_search; -DSPContext dsp; +MLPDSPContext dsp; } MLPEncodeContext; static ChannelParams restart_channel_params[MAX_CHANNELS]; static DecodingParams restart_decoding_params[MAX_SUBSTREAMS];@@ -31,6 +31,11 @@ #define MLP_MIN_LPC_SHIFT 8 #define MLP_MAX_LPC_SHIFT 15 #define FF_LPC_TYPE_DEFAULT -1 +typedef struct MlpLPCContext { + int lpc_order; + int lpc_coeff[MLP_MAX_LPC_ORDER+1]; + int lpc_quant; +} MlpLPCContext; typedef struct { uint8_t min_channel; ///< The index of the first channel coded in this substream. uint8_t max_channel; ///< The index of the last channel coded in this substream. @@ -143,6 +148,8 @@ typedef struct { DecodingParams *seq_decoding_params; unsigned int max_codebook_search; MLPDSPContext dsp; + MlpLPCContext lpc[2]; + LPCContext lpc_ctx; } MLPEncodeContext; static ChannelParams restart_channel_params[MAX_CHANNELS]; static DecodingParams restart_decoding_params[MAX_SUBSTREAMS]; @@ -1157,7 +1164,7 @@ unsigned int substr) *lpc_samples++ = *sample_buffer; sample_buffer += ctx->num_channels; } - order = ff_lpc_calc_coefs(&ctx->dsp, ctx->lpc_sample_buffer, ctx->number_of_samples, + order = ff_lpc_calc_coefs(&ctx->lpc_ctx, ctx->lpc_sample_buffer, ctx->number_of_samples, MLP_MIN_LPC_ORDER, max_order, 11, coefs, shift, -1, 1, ORDER_METHOD_EST, MLP_MIN_LPC_SHIFT, MLP_MAX_LPC_SHIFT, MLP_MIN_LPC_SHIFT); @@ -1815,12 +1815,10 @@ unsigned int substr) /****************************************************************************/ static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr) { - const uint8_t* data=frame->data; - int buf_size=pkt->size; - uint8_t *buf=pkt->data; MLPEncodeContext *ctx = avctx->priv_data; unsigned int bytes_written = 0; - int restart_frame; + int restart_frame,ret; + const int16_t *samples = (const int16_t *)frame->data[0]; ctx->frame_index = avctx->frame_number % ctx->max_restart_interval; ctx->inout_buffer = ctx->major_inout_buffer + ctx->frame_index * ctx->one_sample_buffer_size; @@ -1831,7 +1829,7 @@ unsigned int substr) + ctx->frame_index * ctx->one_sample_buffer_size; ctx->write_buffer = ctx->inout_buffer; if (avctx->frame_number < ctx->max_restart_interval) { - if (data) { + if (frame) { goto input_and_return; } else { /* There are less frames than the requested major header interval. @@ -1861,11 +1859,11 @@ unsigned int substr) ctx->timestamp += ctx->frame_size[ctx->frame_index]; ctx->dts += ctx->frame_size[ctx->frame_index]; input_and_return: - if (data) { - ctx->frame_size[ctx->frame_index] = avctx->frame_size; - ctx->next_major_frame_size += avctx->frame_size; + if (frame) { + ctx->frame_size[ctx->frame_index] = frame->nb_samples; + ctx->next_major_frame_size += frame->nb_samples; ctx->next_major_number_of_frames++; - input_data(ctx, data); + input_data(ctx, samples); } else if (!ctx->last_frame) { ctx->last_frame = ctx->inout_buffer; } @@ -1913,7 +1911,10 @@ unsigned int substr) } } no_data_left: - return bytes_written; + // return bytes_written; + pkt->size = bytes_written; + *got_packet_ptr = 1; + return 0; } static av_cold int mlp_encode_close(AVCodecContext *avctx) {@@ -1818,7 +1818,7 @@ unsigned int substr) MLPEncodeContext *ctx = avctx->priv_data; unsigned int bytes_written = 0; int restart_frame,ret; - const int16_t *samples = (const int16_t *)frame->data[0]; + const int8_t *samples = (const int8_t *)frame->data[0]; ctx->frame_index = avctx->frame_number % ctx->max_restart_interval; ctx->inout_buffer = ctx->major_inout_buffer + ctx->frame_index * ctx->one_sample_buffer_size;@@ -428,12 +429,12 @@ if (avctx->channels <= 2) { ctx->substream_info |= SUBSTREAM_INFO_MAX_2_CHAN; } switch (avctx->sample_fmt) { -case SAMPLE_FMT_S16: +case AV_SAMPLE_FMT_S16: ctx->coded_sample_fmt[0] = BITS_16; ctx->wordlength = 16; break; /* TODO 20 bits: */ -case SAMPLE_FMT_S32: +case AV_SAMPLE_FMT_S32: ctx->coded_sample_fmt[0] = BITS_24; ctx->wordlength = 24; break; @@ -1045,7 +1046,7 @@ ctx->max_output_bits[ctx->frame_index] = number_sbits(greatest); /** Wrapper function for inputting data in two different bit-depths. */ static void input_data(MLPEncodeContext *ctx, void *samples) { -if (ctx->avctx->sample_fmt == SAMPLE_FMT_S32) +if (ctx->avctx->sample_fmt == AV_SAMPLE_FMT_S32) input_data_internal(ctx, samples, 1); else input_data_internal(ctx, samples, 0); @@ -1156,7 +1157,7 @@ sample_buffer += ctx->num_channels; } order = ff_lpc_calc_coefs(&ctx->dsp, ctx->lpc_sample_buffer, ctx->number_of_samples, MLP_MIN_LPC_ORDER, max_order, 11, -coefs, shift, 1, +coefs, shift, -1, 1, ORDER_METHOD_EST, MLP_MIN_LPC_SHIFT, MLP_MAX_LPC_SHIFT, MLP_MIN_LPC_SHIFT); fp->order = order; fp->shift = shift[order-1]; @@ -1570,7 +1571,7 @@ int32_t *sample_buffer = ctx->sample_buffer; unsigned int mat, i, maxchan; maxchan = ctx->num_channels; for (mat = 0; mat < mp->count; mat++) { -unsigned int msb_mask_bits = (ctx->avctx->sample_fmt == SAMPLE_FMT_S16 ? 8 : 0) - mp->shift[mat]; +unsigned int msb_mask_bits = (ctx->avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 8 : 0) - mp->shift[mat]; int32_t mask = MSB_MASK(msb_mask_bits); unsigned int outch = mp->outch[mat]; sample_buffer = ctx->sample_buffer; @@ -1918,14 +1918,15 @@ av_freep(&ctx->frame_size); return 0; } AVCodec ff_mlp_encoder = { -"mlp", -AVMEDIA_TYPE_AUDIO, -CODEC_ID_MLP, -sizeof(MLPEncodeContext), -mlp_encode_init, -mlp_encode_frame, -mlp_encode_close, -.capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY, -.sample_fmts = (enum SampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_S32,SAMPLE_FMT_NONE}, -.long_name = NULL_IF_CONFIG_SMALL("MLP (Meridian Lossless Packing)"), +.name ="mlp", +.long_name = NULL_IF_CONFIG_SMALL("MLP (Meridian Lossless Packing)"), +.type =AVMEDIA_TYPE_AUDIO, +.id =CODEC_ID_MLP, +.priv_data_size =sizeof(MLPEncodeContext), +.init =mlp_encode_init, +.encode2 =mlp_encode_frame, +.close =mlp_encode_close, +.capabilities =CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY, +.sample_fmts = (enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_S32,AV_SAMPLE_FMT_NONE}, + }; @@ -536,7 +536,8 @@ rh->max_matrix_channel = 1; } clear_channel_params(ctx, restart_channel_params); clear_decoding_params(ctx, restart_decoding_params); -dsputil_init(&ctx->dsp, avctx); +ff_audiodsp_init(&ctx->dsp); return 0; } /**************************************************************************** @@ -972,9 +972,10 @@ AV_WB16(frame_header , access_unit_header); AV_WB16(frame_header+2, ctx->dts ); } /** Writes an entire access unit to the bitstream. */ -static unsigned int write_access_unit(MLPEncodeContext *ctx, uint8_t *buf, -int buf_size, int restart_frame) +static unsigned int write_access_unit(MLPEncodeContext *ctx, AVPacket *pkt, int restart_frame) { + uint8_t* buf=pkt->data; +int buf_size=pkt->size; uint16_t substream_data_len[MAX_SUBSTREAMS]; uint8_t *buf2, *buf1, *buf0 = buf; unsigned int substr; @@ -998,7 +999,7 @@ buf += 2; buf_size -= 2; } buf2 = buf; -buf = write_substrs(ctx, buf, buf_size, restart_frame, substream_data_len); +buf = write_substrs(ctx, buf2, buf_size, restart_frame, substream_data_len); total_length = buf - buf0; write_frame_headers(ctx, buf0, buf1, total_length / 2, restart_frame, substream_data_len); return total_length; @@ -1045,7 +1046,7 @@ ctx->max_output_bits[ctx->frame_index] = number_sbits(greatest); } } /** Wrapper function for inputting data in two different bit-depths. */ -static void input_data(MLPEncodeContext *ctx, void *samples) +static void input_data(MLPEncodeContext *ctx, const uint8_t *samples) { if (ctx->avctx->sample_fmt == AV_SAMPLE_FMT_S32) input_data_internal(ctx, samples, 1); @@ -1805,9 +1806,11 @@ apply_filter(ctx, channel); } } /****************************************************************************/ -static int mlp_encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, -void *data) +static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr) { +const uint8_t* data=frame->data; +int buf_size=pkt->size; +uint8_t *buf=pkt->data; MLPEncodeContext *ctx = avctx->priv_data; unsigned int bytes_written = 0; int restart_frame; @@ -1847,7 +1850,7 @@ process_major_frame(ctx); if (ctx->min_restart_interval == ctx->max_restart_interval) ctx->write_buffer = ctx->sample_buffer; avctx->coded_frame->key_frame = restart_frame; -bytes_written = write_access_unit(ctx, buf, buf_size, restart_frame); +bytes_written = write_access_unit(ctx, pkt, restart_frame); ctx->timestamp += ctx->frame_size[ctx->frame_index]; ctx->dts += ctx->frame_size[ctx->frame_index]; input_and_return: ======================================================= libavcodec/mlp.h @@ -74,7 +74,9 @@ typedef struct FilterParams { uint8_t order; ///< number of taps in filter uint8_t shift; ///< Right shift to apply to output of filter. - + int32_t coeff[MAX_FIR_ORDER]; + int coeff_bits; +int coeff_shift; int32_t state[MAX_FIR_ORDER]; } FilterParams; @@ -98,6 +98,41 @@ typedef struct ChannelParams { */ extern const uint8_t ff_mlp_huffman_tables[3][18][2]; +typedef struct { + uint8_t channel_occupancy; + uint8_t group1_channels; + uint8_t group2_channels; + uint8_t summary_info; +} ChannelInformation; + +/** Tables defining channel information. ++ * ++ * Possible channel arrangements are: ++ * ++ * (Group 1) C ++ * (Group 1) L, R ++ * (Group 1) Lf, Rf / (Group 2) S ++ * (Group 1) Lf, Rf / (Group 2) Ls, Rs ++ * (Group 1) Lf, Rf / (Group 2) LFE ++ * (Group 1) Lf, Rf / (Group 2) LFE, S ++ * (Group 1) Lf, Rf / (Group 2) LFE, Ls, Rs ++ * (Group 1) Lf, Rf / (Group 2) C ++ * (Group 1) Lf, Rf / (Group 2) C, S ++ * (Group 1) Lf, Rf / (Group 2) C, Ls, Rs ++ * (Group 1) Lf, Rf / (Group 2) C, LFE ++ * (Group 1) Lf, Rf / (Group 2) C, LFE, S ++ * (Group 1) Lf, Rf / (Group 2) C, LFE, Ls, Rs ++ * (Group 1) Lf, Rf C / (Group 2) S ++ * (Group 1) Lf, Rf C / (Group 2) Ls, Rs ++ * (Group 1) Lf, Rf C / (Group 2) LFE ++ * (Group 1) Lf, Rf C / (Group 2) LFE, S ++ * (Group 1) Lf, Rf C / (Group 2) LFE, Ls, Rs ++ * (Group 1) Lf, Rf Ls Rs / (Group 2) LFE ++ * (Group 1) Lf, Rf Ls Rs / (Group 2) C ++ * (Group 1) Lf, Rf, Ls, Rs / (Group 2) C, LFE ++ */ +extern ChannelInformation ff_mlp_ch_info[21]; + /** MLP uses checksums that seem to be based on the standard CRC algorithm, but * are not (in implementation terms, the table lookup and XOR are reversed). * We can implement this behavior using a standard av_crc on all but the ================================================== libavcodec/lpc.h @@ -90,7 +90,7 @@ int ff_lpc_calc_coefs(LPCContext *s, int max_order, int precision, int32_t coefs[][MAX_LPC_ORDER], int *shift, enum FFLPCType lpc_type, int lpc_passes, - int omethod, int max_shift, int zero_shift); + int omethod, int max_shift,int min_shift, int zero_shift); int ff_lpc_calc_ref_coefs(LPCContext *s, ==================================================== libavcodec/lpc.c @@ -87,7 +87,7 @@ static void lpc_compute_autocorr_c(const double *data, int len, int lag, * Quantize LPC coefficients */ static void quantize_lpc_coefs(double *lpc_in, int order, int precision, - int32_t *lpc_out, int *shift, int max_shift, int zero_shift) + int32_t *lpc_out, int *shift, int max_shift,int min_shift, int zero_shift) { int i; double cmax, error; @@ -112,7 +112,7 @@ static void quantize_lpc_coefs(double *lpc_in, int order, int precision, /* calculate level shift which scales max coeff to available bits */ sh = max_shift; - while((cmax * (1 << sh) > qmax) && (sh > 0)) { + while((cmax * (1 << sh) > qmax) && (sh > min_shift)) { sh--; } @@ -172,7 +172,7 @@ int ff_lpc_calc_coefs(LPCContext *s, int max_order, int precision, int32_t coefs[][MAX_LPC_ORDER], int *shift, enum FFLPCType lpc_type, int lpc_passes, - int omethod, int max_shift, int zero_shift) + int omethod, int min_shift, int max_shift, int zero_shift) { double autoc[MAX_LPC_ORDER+1]; double ref[MAX_LPC_ORDER]; @@ -255,10 +255,10 @@ int ff_lpc_calc_coefs(LPCContext *s, if(omethod == ORDER_METHOD_EST) { opt_order = estimate_best_order(ref, min_order, max_order); i = opt_order-1; - quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift); + quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], min_shift, max_shift, zero_shift); } else { for(i=min_order-1; i<max_order; i++) { - quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift); + quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], min_shift, max_shift, zero_shift); } } ====================================================== libavcodec/flacenc.c @@ -44,7 +44,7 @@ #define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER) #define MAX_LPC_PRECISION 15 #define MAX_LPC_SHIFT 15 - + #define MIN_LPC_SHIFT 0 enum CodingMode { CODING_MODE_RICE = 4, CODING_MODE_RICE2 = 5, @@ -815,8 +815,7 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) sub->type = FLAC_SUBFRAME_LPC; opt_order = ff_lpc_calc_coefs(&s->lpc_ctx, smp, n, min_order, max_order, s->options.lpc_coeff_precision, coefs, shift, s->options.lpc_type, - s->options.lpc_passes, omethod, - MAX_LPC_SHIFT, 0); + s->options.lpc_passes, omethod, MIN_LPC_SHIFT, MAX_LPC_SHIFT, 0); if (omethod == ORDER_METHOD_2LEVEL || omethod == ORDER_METHOD_4LEVEL || ======================================================== libavcodec/alacenc.c @@ -166,9 +166,7 @@ static void calc_predictor_params(AlacEncodeContext *s, int ch) s->frame_size, s->min_prediction_order, s->max_prediction_order, - ALAC_MAX_LPC_PRECISION, coefs, shift, - FF_LPC_TYPE_LEVINSON, 0, - ORDER_METHOD_EST, ALAC_MAX_LPC_SHIFT, 1); + ALAC_MAX_LPC_PRECISION, coefs, shift, -1, 1, ORDER_METHOD_EST, 0, ALAC_MAX_LPC_SHIFT, 1); s->lpc[ch].lpc_order = opt_order; s->lpc[ch].lpc_quant = shift[opt_order-1]; ============================================================== libavcodec/Makefile @@ -297,6 +297,7 @@ OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o mjpeg.o OBJS-$(CONFIG_MJPEG_ENCODER) += mjpegenc.o mjpeg.o mjpegenc_common.o OBJS-$(CONFIG_MJPEGB_DECODER) += mjpegbdec.o OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o +OBJS-$(CONFIG_MLP_ENCODER) += mlpenc.o mlp.o OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o OBJS-$(CONFIG_MOTIONPIXELS_DECODER) += motionpixels.o OBJS-$(CONFIG_MOVTEXT_DECODER) += movtextdec.o ass.o =========================================================== libavcodec/allcodecs.c @@ -357,6 +357,7 @@ void avcodec_register_all(void) REGISTER_DECODER(MACE6, mace6); REGISTER_DECODER(METASOUND, metasound); -REGISTER_DECODER(MLP, mlp); + REGISTER_ENCDEC (MLP, mlp); REGISTER_DECODER(MP1, mp1); REGISTER_DECODER(MP1FLOAT, mp1float); REGISTER_ENCDEC (MP2, mp2); ========================================================== libavcodec/version.h @@ -29,7 +29,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 56 -#define LIBAVCODEC_VERSION_MINOR 8 +#define LIBAVCODEC_VERSION_MINOR 9 #define LIBAVCODEC_VERSION_MICRO 102 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ =================================================== libavcodec/ra144enc.c @@ -475,7 +475,7 @@ static int ra144_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, ff_lpc_calc_coefs(&ractx->lpc_ctx, lpc_data, NBLOCKS * BLOCKSIZE, LPC_ORDER, LPC_ORDER, 16, lpc_coefs, shift, 0, FF_LPC_TYPE_LEVINSON, - 0, ORDER_METHOD_EST, 12, 0); + 1, ORDER_METHOD_EST, 12, 0 , 0); for (i = 0; i < LPC_ORDER; i++) block_coefs[NBLOCKS - 1][i] = -(lpc_coefs[LPC_ORDER - 1][i] << (12 - shift[LPC_ORDER - 1])); }; I have unchecked the flags -Werror=vla ,implicit_function_declaration Greeshma _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel