[FFmpeg-devel] Fwd: "OPW Qualification Task: Validate MLP Bitstream

greeshma greeshmabalabadra at gmail.com
Fri Oct 31 15:41:49 CET 2014


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 <greeshmabalabadra at 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 Balabhadra


More information about the ffmpeg-devel mailing list