[FFmpeg-devel] [RFC v4] libbavcodec: add a native decoder for the Daala video codec

Andreas Cadhalpun andreas.cadhalpun at googlemail.com
Sat Jan 2 13:11:52 CET 2016


On 01.01.2016 21:16, Rostislav Pehlivanov wrote:
> Thanks for the feedback.
> Fixed all the issues you reported. The new revision is in this email.

Thanks. Unfortunately you introduced a much more serious crash problem.

Also, there is now a typo "libbavcodec" (two 'b') in the subject.

> --- /dev/null
> +++ b/libavcodec/daaladec.c
> @@ -0,0 +1,810 @@
[...]
> +static av_cold int daala_decode_init(AVCodecContext *avctx)
> +{
> +    int i, r_w, r_h, err = 0;
> +    DaalaContext *s = avctx->priv_data;
> +
> +    /* Inits a default QM, if the file isn't using the default it will be reinit */
> +    s->last_qm = 1;
> +    daala_init_qmatrix(s->pvq.qmatrix, s->pvq.qmatrix_inv, s->last_qm);
> +
> +    s->fmt = find_pix_fmt(avctx->pix_fmt);
> +    if (!s->fmt) {
> +        av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format - %s!\n",
> +               av_get_pix_fmt_name(avctx->pix_fmt));
> +        return AVERROR(ENOTSUP);
> +    }
> +
> +    if (ff_daaladsp_init(&s->dsp, s->fmt->depth)) {
> +        av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth - %i!\n",
> +               s->fmt->depth);
> +        return AVERROR(ENOTSUP);
> +    }
> +
> +    /* Can be turned on for 8 bit files too and the demuxer gets it, but how
> +     * the hell to actually get that flag from the demuxer to this decoder? */
> +    s->fpr = s->fmt->depth > 8 ? 1 : 0;
> +
> +    s->width  = FFALIGN(avctx->width,  DAALA_BSIZE_MAX);
> +    s->height = FFALIGN(avctx->height, DAALA_BSIZE_MAX);

There used to be a loop over i here, but now i is uninitialized.

> +    r_w = s->width  >> s->fmt->dec[i][0];
> +    r_h = s->height >> s->fmt->dec[i][1];

Thus this basically always crashes.
Therefore I can't test any further until this is resolved.

> +    s->sbn_x = s->width  >> DAALA_LOG_BSIZE_MAX;
> +    s->sbn_y = s->height >> DAALA_LOG_BSIZE_MAX;
> +
> +    /* Block sizes array */
> +    s->bsizes_stride = (s->sbn_x + 2)*DAALA_BSIZE_GRID;
> +    s->bsizes = av_malloc(sizeof(enum DaalaBsize)*s->bsizes_stride*(s->sbn_y + 2)*DAALA_BSIZE_GRID);
> +    if (!s->bsizes)
> +        return AVERROR(ENOMEM);
> +
> +    /* Like motion vectors, this could be outside the image, so shift it */
> +    s->bsizes += DAALA_BSIZE_GRID*s->bsizes_stride + DAALA_BSIZE_GRID;
> +
> +    /*  CDF init */
> +    err |= daalaent_cdf_alloc(&s->dering_cdf, 4, 2, 128, 0, 2, 0);
> +    err |= daalaent_cdf_alloc(&s->q_scale_cdf, 8, 4, 128, 0, 2, 0);
> +    err |= daalaent_cdf_alloc(&s->haar_bit_cdf, 3, 16, 128, 0, 2, 0);
> +    err |= daalaent_cdf_alloc(&s->haar_split_cdf, 15*2*5, 16, 128, 0, 2, 0);
> +    err |= daalaent_cdf_alloc(&s->skip_cdf, DAALA_NBSIZES*2, 5, 128, 0, 2, 0);
> +    err |= daalaent_cdf_alloc(&s->haar_coef_cdf, 15*3*(DAALA_NBSIZES+1), 16, 128, 0, 2, 0);
> +    for (i = 0; i < s->fmt->planes; i++)
> +        err |= daalaent_cdf_alloc(&s->haar_dc_mcdf[i], DAALAENT_MODEL_TAB, 16, 64, 0, 0, 1);
> +
> +    /* PVQ CDFs */
> +    err |= daalaent_cdf_alloc(&s->pvq.pvqcodeword_cdf, 4, 16, 128, 0, 0, 0);
> +    err |= daalaent_cdf_alloc(&s->pvq.pvqskip_cdf, 2*(DAALA_NBSIZES-1), 7, 128, 0, 2, 0);
> +    err |= daalaent_cdf_alloc(&s->pvq.pvqtheta_gain_cdf, 2*DAALA_NBSIZES*DAALAPVQ_PARTITIONS_MAX, 16, 128, 0, 2, 0);
> +    err |= daalaent_cdf_alloc(&s->pvq.pvqtheta_mcdf, DAALAENT_MODEL_TAB, 16, 64, 0, 0, 1);
> +    err |= daalaent_cdf_alloc(&s->pvq.pvqgain_ref_mcdf, DAALAENT_MODEL_TAB, 16, 64, 0, 0, 1);
> +    err |= daalaent_cdf_alloc(&s->pvq.pvqgain_noref_mcdf, DAALAENT_MODEL_TAB, 16, 64, 0, 0, 1);
> +
> +    /* The allocations above are unlikely to fail so checking here is okay */
> +    if (err)
> +        goto alloc_fail;
> +
> +    /* Arrays */
> +    DAALA_ALLOC_2D_ARRAY_GOTO(s->dering, s->sbn_x, s->sbn_y, uint8_t, alloc_fail);
> +    DAALA_ALLOC_2D_ARRAY_GOTO(s->q_scale, s->sbn_x, s->sbn_y, uint8_t, alloc_fail);
> +    DAALA_ALLOC_STATIC_2D_ARRAY_GOTO(s->haar_dc_buf, s->fmt->planes, s->sbn_x,
> +                                     s->sbn_y, dctcoef, alloc_fail);
> +
> +    /* Coefficients, still too much */
> +    s->lcoef    = av_malloc(r_w*r_h*sizeof(dctcoef));

Here r_w and r_h are used, but they depend on i and previously there was an array of coefs...
It seems you wanted to eliminate that, but something went quite wrong.

> +    if (!s->lcoef)
> +        goto alloc_fail;
> +
> +    s->dcoef[0] = av_malloc(r_w*r_h*sizeof(dctcoef));
> +    if (!s->dcoef[0])
> +        goto alloc_fail;
> +
> +    s->dcoef[1] = av_malloc(r_w*r_h*sizeof(dctcoef));
> +    s->dcoef[3] = s->dcoef[2] = s->dcoef[1];
> +    if (!s->dcoef[1])
> +        goto alloc_fail;
> +
> +    for (i = 0; i < s->fmt->planes; i++) {
> +        s->ccoef[i] = av_malloc(r_w*r_h*sizeof(dctcoef));
> +        if (!s->ccoef[i])
> +            goto alloc_fail;
> +    }
> +
> +    return 0;
> +
> +alloc_fail:
> +    av_log(avctx, AV_LOG_ERROR, "Failed to allocate memory!\n");
> +    daala_decode_free(avctx);
> +    return AVERROR(ENOMEM);
> +}
> +
> +AVCodec ff_daala_decoder = {
> +    .name           = "daala",
> +    .long_name      = NULL_IF_CONFIG_SMALL("Daala"),
> +    .type           = AVMEDIA_TYPE_VIDEO,
> +    .id             = AV_CODEC_ID_DAALA,
> +    .priv_data_size = sizeof(DaalaContext),
> +    .init           = daala_decode_init,
> +    .close          = daala_decode_free,
> +    .decode         = daala_decode_frame,

Please add:
    .capabilities   = AV_CODEC_CAP_EXPERIMENTAL,

At least until non-I-frames are supported.

Happy new year,
Andreas


More information about the ffmpeg-devel mailing list