[FFmpeg-devel] [PATCH] Cineform HD Decoder:

Michael Niedermayer michael at niedermayer.cc
Mon Jan 4 17:51:50 CET 2016


On Mon, Jan 04, 2016 at 12:04:08AM +0000, Kieran Kunhya wrote:
> Decodes YUV422P10 samples in AVI and MOV (Gopro Studio)
> Older files with more subbands, skips, Bayer not supported
> ---
>  libavcodec/Makefile     |   1 +
>  libavcodec/allcodecs.c  |   1 +
>  libavcodec/avcodec.h    |   1 +
>  libavcodec/cfhd.c       | 567 ++++++++++++++++++++++++++++++++++++++++++++++++
>  libavcodec/cfhd.h       |  97 +++++++++
>  libavcodec/cfhddata.c   | 466 +++++++++++++++++++++++++++++++++++++++
>  libavcodec/codec_desc.c |   6 +

>  libavformat/riff.c      |   1 +

ideally the avformat change should be a seperate commit


>  8 files changed, 1140 insertions(+)
>  create mode 100644 libavcodec/cfhd.c
>  create mode 100644 libavcodec/cfhd.h
>  create mode 100644 libavcodec/cfhddata.c
> 
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index a18ca5b..9db88d7 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -212,6 +212,7 @@ OBJS-$(CONFIG_CDGRAPHICS_DECODER)      += cdgraphics.o
>  OBJS-$(CONFIG_CDXL_DECODER)            += cdxl.o
>  OBJS-$(CONFIG_CINEPAK_DECODER)         += cinepak.o
>  OBJS-$(CONFIG_CINEPAK_ENCODER)         += cinepakenc.o elbg.o
> +OBJS-$(CONFIG_CFHD_DECODER)            += cfhd.o cfhddata.o
>  OBJS-$(CONFIG_CLJR_DECODER)            += cljrdec.o
>  OBJS-$(CONFIG_CLJR_ENCODER)            += cljrenc.o
>  OBJS-$(CONFIG_CLLC_DECODER)            += cllc.o canopus.o
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index 4eeb6f3..ca6e4c2 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -147,6 +147,7 @@ void avcodec_register_all(void)
>      REGISTER_DECODER(CAVS,              cavs);
>      REGISTER_DECODER(CDGRAPHICS,        cdgraphics);
>      REGISTER_DECODER(CDXL,              cdxl);
> +    REGISTER_DECODER(CFHD,              cfhd);
>      REGISTER_ENCDEC (CINEPAK,           cinepak);
>      REGISTER_ENCDEC (CLJR,              cljr);
>      REGISTER_DECODER(CLLC,              cllc);
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index f365775..b958a6c 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -315,6 +315,7 @@ enum AVCodecID {
>      AV_CODEC_ID_SMVJPEG,
>      AV_CODEC_ID_APNG,
>      AV_CODEC_ID_DAALA,
> +    AV_CODEC_ID_CFHD,
>  
>      /* various PCM "codecs" */
>      AV_CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
> diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c
> new file mode 100644
> index 0000000..0f1bcd3
> --- /dev/null
> +++ b/libavcodec/cfhd.c
> @@ -0,0 +1,567 @@
> +/*
> + * Copyright (c) 2015 Kieran Kunhya
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +/**
> + * @file
> + * CFHD Video Decoder
> + */
> +
> +#include "avcodec.h"
> +#include "bswapdsp.h"
> +#include "internal.h"
> +#include "cfhd.h"
> +#include "libavutil/avassert.h"
> +#include "libavutil/buffer.h"
> +#include "libavutil/common.h"
> +#include "libavutil/intreadwrite.h"
> +#include "libavutil/imgutils.h"
> +#include "libavutil/opt.h"
> +
> +static av_cold int cfhd_init_decoder(AVCodecContext *avctx)
> +{
> +    CFHDContext *s = avctx->priv_data;
> +
> +    ff_cfhd_init_vlcs(s);
> +
> +    avctx->pix_fmt             = AV_PIX_FMT_YUV422P10;
> +    avctx->bits_per_raw_sample = 16;
> +    s->avctx                   = avctx;
> +
> +    return 0;
> +}
> +
> +static void init_plane_defaults(CFHDContext *s)
> +{
> +    s->subband_num        = 0;
> +    s->level              = 0;
> +    s->subband_num_actual = 0;
> +}
> +
> +static void init_frame_defaults(CFHDContext *s)
> +{
> +    s->bpc               = 10;
> +    s->channel_cnt       = 4;
> +    s->subband_cnt       = 10;
> +    s->channel_num       = 0;
> +    s->lowpass_precision = 16;
> +    s->quantisation      = 1;
> +    s->wavelet_depth     = 3;
> +    s->pshift            = 1;
> +    s->codebook          = 0;
> +    init_plane_defaults(s);
> +}
> +
> +static inline int dequant_and_decompand(int level, int quantisation)
> +{
> +    int abslevel = abs(level);
> +    return (abslevel + ((768 * abslevel * abslevel * abslevel) / (255 * 255 * 255))) * FFSIGN(level) * quantisation;
> +}
> +
> +static inline void filter(int16_t *output, int out_stride, int16_t *low, int low_stride,
> +                          int16_t *high, int high_stride, int len)
> +{
> +    int32_t tmp, tmp2;
> +    int16_t tmp3, tmp4;
> +
> +    /* these refer to the coefficients for the *next* iteration */
> +    int16_t l_0, l_1, l_2, l_m1, l_m2;
> +    int16_t h_0;
> +
> +    int i;
> +    for (i = 0; i < len; i++) {
> +        if (i == 0) {
> +            l_2  = low[3 * low_stride];
> +            l_1  = low[2 * low_stride];
> +            l_0  = low[1 * low_stride];
> +            l_m1 = low[0 * low_stride];
> +            l_m2 = 0;
> +            h_0  = high[1 * high_stride];
> +
> +            tmp   = (11 * l_m1 - 4 * l_0 + l_1 + 4) >> 3;
> +            tmp2  = (5 * l_m1 + 4 * l_0 - l_1 + 4) >> 3;
> +
> +            output[(2 * i + 0) * out_stride] = (tmp + high[0 * high_stride]) >> 1;
> +            output[(2 * i + 1) * out_stride] = (tmp2 - high[0 * high_stride]) >> 1;
> +        } else if (i == len - 1) {
> +            tmp = (5 * l_0 + 4 * l_m1 - l_m2 + 4) >> 3;
> +            output[(2 * i + 0) * out_stride] = (tmp + h_0) >> 1;
> +            tmp = (11 * l_0 - 4 * l_m1 + l_m2 + 4) >> 3;
> +            output[(2 * i + 1) * out_stride] = (tmp - h_0) >> 1;
> +        } else {
> +            tmp  = (l_m1 - l_1 + 4) >> 3;
> +            tmp2 = (l_1 - l_m1 + 4) >> 3;
> +
> +            tmp3 = (tmp + l_0 + h_0) >> 1;
> +            tmp4 = (tmp2 + l_0 - h_0) >> 1;
> +
> +            l_m2 = l_m1;
> +            l_m1 = l_0;
> +            l_0  = l_1;
> +            l_1  = l_2;
> +            l_2  = low[(i + 3) * low_stride];
> +            h_0  = high[(i + 1) * high_stride];
> +
> +            output[(2 * i + 0) * out_stride] = tmp3;
> +            output[(2 * i + 1) * out_stride] = tmp4;
> +        }
> +    }
> +}
> +
> +static void horiz_filter(int16_t *output, int16_t *low, int16_t *high, int width)
> +{
> +    filter(output, 1, low, 1, high, 1, width);
> +}
> +
> +static void vert_filter(int16_t *output, int out_stride, int16_t *low, int low_stride,
> +                        int16_t *high, int high_stride, int len)
> +{
> +    filter(output, out_stride, low, low_stride, high, high_stride, len);
> +}
> +
> +static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
> +                       AVPacket *avpkt)
> +{
> +    CFHDContext *s = avctx->priv_data;
> +    uint8_t *bs = avpkt->data;
> +    int cnt = 0;
> +    AVFrame *pic = data;
> +    int ret = 0, i, j;
> +    int16_t *plane[3];
> +    int16_t *tmp[3];
> +    int16_t *subband[3][10] = {{0}};
> +    int16_t *l_h[3][8];
> +
> +    avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift);
> +
> +    for (i = 0; i < 3; i++) {
> +        int width = i ? avctx->width >> s->chroma_x_shift : avctx->width;
> +        int height = i ? avctx->height >> s->chroma_y_shift : avctx->height;
> +        height = FFALIGN(height / 8, 2) * 8;
> +        int stride = FFALIGN(width / 8, 8) * 8;
> +        s->plane[i].width = width;
> +        s->plane[i].height = height;
> +        s->plane[i].stride = stride;
> +
> +        int w8 = FFALIGN(s->plane[i].width / 8, 8);
> +        int h8 = FFALIGN(s->plane[i].height / 8, 2);
> +        int w4 = w8 * 2;
> +        int h4 = h8 * 2;
> +        int w2 = w4 * 2;
> +        int h2 = h4 * 2;
> +

> +        plane[i] = av_malloc(height * stride * sizeof(*plane[i]));
> +        tmp[i]   = av_malloc(height * stride * sizeof(*plane[i]));
> +
> +        subband[i][0] = plane[i];

missing malloc failure checks


> +        subband[i][1] = plane[i] + 2 * w8 * h8;
> +        subband[i][2] = plane[i] + 1 * w8 * h8;
> +        subband[i][3] = plane[i] + 3 * w8 * h8;
> +        subband[i][4] = plane[i] + 2 * w4 * h4;
> +        subband[i][5] = plane[i] + 1 * w4 * h4;
> +        subband[i][6] = plane[i] + 3 * w4 * h4;
> +        subband[i][7] = plane[i] + 2 * w2 * h2;
> +        subband[i][8] = plane[i] + 1 * w2 * h2;
> +        subband[i][9] = plane[i] + 3 * w2 * h2;
> +
> +        l_h[i][0] = tmp[i];
> +        l_h[i][1] = tmp[i] + 2 * w8 * h8;
> +        //l_h[i][2] = ll2;
> +        l_h[i][3] = tmp[i];
> +        l_h[i][4] = tmp[i] + 2 * w4 * h4;
> +        //l_h[i][5] = ll1;
> +        l_h[i][6] = tmp[i];
> +        l_h[i][7] = tmp[i] + 2 * w2 * h2;
> +    }
> +
> +    init_frame_defaults(s);
> +
> +    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
> +        return ret;
> +
> +    while (cnt < avpkt->size) {
> +        int16_t tag     = AV_RB16(&bs[cnt]);
> +        int8_t tag8     = (int8_t)bs[cnt];
> +        uint16_t abstag = abs(tag);
> +        int8_t abs_tag8 = abs(tag8);
> +        uint16_t data   = AV_RB16(&bs[cnt + 2]);
> +        if (abs_tag8 >= 0x60 && abs_tag8 <= 0x6f) {
> +            av_log(avctx, AV_LOG_DEBUG, "large len %x \n", AV_RB24(&bs[cnt + 1]));
> +        } else if (tag == 20) {
> +            av_log(avctx, AV_LOG_DEBUG, "Width %u %x \n", data, cnt);
> +            avctx->width = data;
> +        } else if (tag == 21) {
> +            av_log(avctx, AV_LOG_DEBUG, "Height %u %x \n", data, cnt);
> +            avctx->height = data;
> +        } else if (tag == 101) {
> +            av_log(avctx, AV_LOG_DEBUG, "Bits per component: %u \n", data);
> +            s->bpc = data;

the debug av_logs could be put under some
if (avctx->debug & FF_DEBUG_*)

that way they can be enabled when needed and dont clutter the output
when not



> +        } else if (tag == 12) {
> +            av_log(avctx, AV_LOG_DEBUG, "Channel Count: %u \n", data);
> +            s->channel_cnt = data;
> +            if (data != 3) {
> +                av_log(avctx, AV_LOG_ERROR, "Channel Count of %u is unsupported\n", data);
> +                ret = AVERROR_PATCHWELCOME;
> +                break;
> +            }
> +        } else if (tag == 14) {
> +            av_log(avctx, AV_LOG_DEBUG, "Subband Count: %u \n", data);
> +            if (data != 10) {
> +                av_log(avctx, AV_LOG_ERROR, "Subband Count of %u is unsupported\n", data);
> +                ret = AVERROR_PATCHWELCOME;
> +                break;
> +            }
> +        }
> +        else if (tag == 62) {
> +            s->channel_num = data;
> +            av_log(avctx, AV_LOG_DEBUG, "Channel number %u \n", data);
> +            init_plane_defaults(s);
> +        } else if (tag == 48) {
> +            if (s->subband_num != 0 && data == 1)  // hack
> +                s->level++;
> +            av_log(avctx, AV_LOG_DEBUG, "Subband number %u \n", data);
> +            s->subband_num = data;
> +        } else if (tag == 51) {
> +            av_log(avctx, AV_LOG_DEBUG, "Subband number actual %u \n", data);
> +            s->subband_num_actual = data;
> +        } else if (tag == 35)
> +            av_log(avctx, AV_LOG_DEBUG, "Lowpass precision bits: %u \n", data);
> +        else if (tag == 53) {
> +            s->quantisation = data;
> +            av_log(avctx, AV_LOG_DEBUG, "Quantisation: %u \n", data);
> +        } else if (tag == 109) {
> +            s->prescale_shift[0] = (data >> 0) & 0x7;
> +            s->prescale_shift[1] = (data >> 3) & 0x7;
> +            s->prescale_shift[2] = (data >> 6) & 0x7;
> +            av_log(avctx, AV_LOG_DEBUG, "Prescale shift (VC-5): %x \n", data);
> +        } else if (tag == 27) {
> +            s->plane[s->channel_num].band[0][0].width  = data;
> +            s->plane[s->channel_num].band[0][0].stride = data;
> +            av_log(avctx, AV_LOG_DEBUG, "Lowpass width %u \n", data);
> +        } else if (tag == 28) {
> +            s->plane[s->channel_num].band[0][0].height = data;
> +            av_log(avctx, AV_LOG_DEBUG, "Lowpass height %u \n", data);
> +        } else if (tag == 1)
> +            av_log(avctx, AV_LOG_DEBUG, "Sample type? %u \n", data);
> +        else if (tag == 10) {
> +            if (data != 0) {
> +                av_log(avctx, AV_LOG_ERROR, "Transform type of %u is unsupported\n", data);
> +                ret = AVERROR_PATCHWELCOME;
> +                break;
> +            }
> +            av_log(avctx, AV_LOG_DEBUG, "Transform-type? %u \n", data);
> +        }
> +        else if (abstag >= 0x4000 && abstag <= 0x40ff) {
> +            av_log(avctx, AV_LOG_DEBUG, "Small chunk length %u %s \n", data * 4, tag < 0 ? "optional" : "required");
> +            cnt += data * 4;
> +        } else if (tag == 23) {
> +            av_log(avctx, AV_LOG_DEBUG, "Skip frame \n");
> +            av_log(avctx, AV_LOG_ERROR, "Skip frame not supported \n");
> +            ret = AVERROR_PATCHWELCOME;
> +            break;
> +        } else if (tag == 2) {
> +            av_log(avctx, AV_LOG_DEBUG, "tag=2 header - skipping %i tag/value pairs \n", data);
> +            for (i = 0; i < data + 1; i++) {
> +                av_log(avctx, AV_LOG_DEBUG, "Tag/Value = %x %x \n", AV_RB16(&bs[cnt]), AV_RB16(&bs[cnt + 2]));
> +                cnt += 4;
> +            }
> +        } else if (tag == 41) {
> +            s->plane[s->channel_num].band[s->level][s->subband_num].width  = data;
> +            s->plane[s->channel_num].band[s->level][s->subband_num].stride = FFALIGN(data, 8);
> +            av_log(avctx, AV_LOG_DEBUG, "Highpass width %i channel %i level %i subband %i \n", data, s->channel_num, s->level, s->subband_num);
> +        } else if (tag == 42) {
> +            s->plane[s->channel_num].band[s->level][s->subband_num].height = data;
> +            av_log(avctx, AV_LOG_DEBUG, "Highpass height %i \n", data);
> +        } else if (tag == 49) {
> +            s->plane[s->channel_num].band[s->level][s->subband_num].width  = data;
> +            s->plane[s->channel_num].band[s->level][s->subband_num].stride = FFALIGN(data, 8);
> +            av_log(avctx, AV_LOG_DEBUG, "Highpass width2 %i \n", data);
> +        } else if (tag == 50) {
> +            s->plane[s->channel_num].band[s->level][s->subband_num].height = data;
> +            av_log(avctx, AV_LOG_DEBUG, "Highpass height2 %i \n", data);
> +        } else if (tag == 71) {
> +            s->codebook = data;
> +            av_log(avctx, AV_LOG_DEBUG, "Codebook %i \n", s->codebook);
> +        } else if (tag == 72) {
> +            s->codebook = data;
> +            av_log(avctx, AV_LOG_DEBUG, "Other codebook? %i \n", s->codebook);
> +        } else
> +            av_log(avctx, AV_LOG_DEBUG,  "Unknown tag %i data %x \n", tag, data);
> +        cnt += 4;
> +

> +        int16_t *coeff_data = subband[s->channel_num][s->subband_num_actual];

this produces:
"warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]"


> +
> +        /* Lowpass coefficients */
> +        if (tag == 4 && data == 0xf0f) {
> +            int lowpass_height = s->plane[s->channel_num].band[0][0].height;
> +            int lowpass_width  = s->plane[s->channel_num].band[0][0].width;
> +            uint16_t coeffs    = 0;
> +            av_log(avctx, AV_LOG_DEBUG, "Start of lowpass coeffs component %u \n", s->channel_num);
> +            for (i = 0; i < lowpass_height; i++) {
> +                for (j = 0; j < lowpass_width; j++) {
> +                    coeff_data[j] = AV_RB16(&bs[cnt]);
> +
> +                    coeffs++;
> +                    cnt += 2;
> +                }
> +                coeff_data += lowpass_width;
> +            }

have the lowpass_height and lowpass_width been checked somewhere
so this wont write ove the array end ?

also the bs array could be too small causin a overread

[...]
> diff --git a/libavcodec/cfhd.h b/libavcodec/cfhd.h
> new file mode 100644
> index 0000000..1a5830e
> --- /dev/null
> +++ b/libavcodec/cfhd.h
> @@ -0,0 +1,97 @@
> +/*
> + * Copyright (c) 2015 Kieran Kunhya
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#include "get_bits.h"
> +
> +#define VLC_BITS 9
> +#define NB_VLC_TABLE_9 (71+3)
> +#define NB_VLC_TABLE_18 (263+1)
> +
> +typedef struct CFHD_RL_VLC_ELEM {
> +    int16_t level;
> +    int8_t len;
> +    uint16_t run;
> +} CFHD_RL_VLC_ELEM;
> +
> +#define DWT_LEVELS 3
> +

> +#define CALC_PADDING(size, depth)                       \
> +    (((size + (1 << depth) - 1) >> depth) << depth)

size ande depth should be protected by () so that when passing
expressions the evaluation order works out

[...]
> +av_cold int ff_cfhd_init_vlcs(CFHDContext *s)
> +{
> +    int i, j;
> +    uint32_t new_cfhd_vlc_bits[NB_VLC_TABLE_18 * 2];
> +    uint8_t  new_cfhd_vlc_len[NB_VLC_TABLE_18 * 2];
> +    uint16_t new_cfhd_vlc_run[NB_VLC_TABLE_18 * 2];
> +    int16_t  new_cfhd_vlc_level[NB_VLC_TABLE_18 * 2];
> +
> +    /** Similar to dv.c, generate signed VLC tables **/
> +
> +    /* Table 9 */
> +    for (i = 0, j = 0; i < NB_VLC_TABLE_9; i++, j++) {
> +        new_cfhd_vlc_bits[j]  = table_9_vlc_bits[i];
> +        new_cfhd_vlc_len[j]   = table_9_vlc_len[i];
> +        new_cfhd_vlc_run[j]   = table_9_vlc_run[i];
> +        new_cfhd_vlc_level[j] = table_9_vlc_level[i];
> +
> +        /* Don't include the zero level nor escape bits */
> +        if (table_9_vlc_level[i] &&
> +            new_cfhd_vlc_bits[j] != table_9_vlc_bits[NB_VLC_TABLE_9-1]) {
> +            new_cfhd_vlc_bits[j] <<= 1;
> +            new_cfhd_vlc_len[j]++;
> +            j++;
> +            new_cfhd_vlc_bits[j]  = (table_9_vlc_bits[i] << 1) | 1;
> +            new_cfhd_vlc_len[j]   =  table_9_vlc_len[i] + 1;
> +            new_cfhd_vlc_run[j]   =  table_9_vlc_run[i];
> +            new_cfhd_vlc_level[j] = -table_9_vlc_level[i];
> +        }
> +    }
> +
> +    init_vlc(&s->vlc_9, VLC_BITS, j, new_cfhd_vlc_len,
> +             1, 1, new_cfhd_vlc_bits, 4, 4, 0);
> +    for (i = 0; i < s->vlc_9.table_size; i++) {
> +        int code = s->vlc_9.table[i][0];
> +        int len  = s->vlc_9.table[i][1];
> +        int level, run;
> +
> +        if (len < 0) { // more bits needed
> +            run   = 0;
> +            level = code;
> +        } else {
> +            run   = new_cfhd_vlc_run[code];
> +            level = new_cfhd_vlc_level[code];
> +        }
> +        s->table_9_rl_vlc[i].len   = len;
> +        s->table_9_rl_vlc[i].level = level;
> +        s->table_9_rl_vlc[i].run   = run;
> +    }
> +
> +    /* Table 18 */
> +    for (i = 0, j = 0; i < NB_VLC_TABLE_18; i++, j++) {
> +        new_cfhd_vlc_bits[j]  = table_18_vlc_bits[i];
> +        new_cfhd_vlc_len[j]   = table_18_vlc_len[i];
> +        new_cfhd_vlc_run[j]   = table_18_vlc_run[i];
> +        new_cfhd_vlc_level[j] = table_18_vlc_level[i];
> +
> +        /* Don't include the zero level nor escape bits */
> +        if (table_18_vlc_level[i] &&
> +            new_cfhd_vlc_bits[j] != table_18_vlc_bits[NB_VLC_TABLE_18-1]) {
> +            new_cfhd_vlc_bits[j] <<= 1;
> +            new_cfhd_vlc_len[j]++;
> +            j++;
> +            new_cfhd_vlc_bits[j]  = (table_18_vlc_bits[i] << 1) | 1;
> +            new_cfhd_vlc_len[j]   =  table_18_vlc_len[i] + 1;
> +            new_cfhd_vlc_run[j]   =  table_18_vlc_run[i];
> +            new_cfhd_vlc_level[j] = -table_18_vlc_level[i];
> +        }
> +    }
> +
> +    init_vlc(&s->vlc_18, VLC_BITS, j, new_cfhd_vlc_len,
> +             1, 1, new_cfhd_vlc_bits, 4, 4, 0);

> +    assert(s->vlc_18.table_size == 4572);

should probably be some av_assert


[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Avoid a single point of failure, be that a person or equipment.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20160104/710430b2/attachment.sig>


More information about the ffmpeg-devel mailing list