
static av_cold int vc2_encode_init(AVCodecContext *avctx)
{
    Plane *p;
    SubBand *b;
    int i, j, level, o, shift;
    VC2EncContext *s = avctx->priv_data;

    s->picture_number = 0;

    /* Total allowed quantization range */
    s->q_ceil    = MAX_QUANT_INDEX;

    s->ver.major = 2;
    s->ver.minor = 0;
    s->profile   = 3;
    s->level     = 3;

    s->base_vf   = -1;
    s->strict_compliance = 1;

    /* Mark unknown as progressive */
    s->interlaced = !((avctx->field_order == AV_FIELD_UNKNOWN) ||
                      (avctx->field_order == AV_FIELD_PROGRESSIVE));

    if (avctx->pix_fmt == AV_PIX_FMT_YUV422P10) {
        if (avctx->width == 1280 && avctx->height == 720) {
            s->level = 3;
            if (avctx->time_base.num == 1001 && avctx->time_base.den == 60000)
                s->base_vf = 9;
            if (avctx->time_base.num == 1 && avctx->time_base.den == 50)
                s->base_vf = 10;
        } else if (avctx->width == 1920 && avctx->height == 1080) {
            s->level = 3;
            if (s->interlaced) {
                if (avctx->time_base.num == 1001 && avctx->time_base.den == 30000)
                    s->base_vf = 11;
                if (avctx->time_base.num == 1 && avctx->time_base.den == 50)
                    s->base_vf = 12;
            } else {
                if (avctx->time_base.num == 1001 && avctx->time_base.den == 60000)
                    s->base_vf = 13;
                if (avctx->time_base.num == 1 && avctx->time_base.den == 50)
                    s->base_vf = 14;
                if (avctx->time_base.num == 1001 && avctx->time_base.den == 24000)
                    s->base_vf = 21;
            }
        } else if (avctx->width == 3840 && avctx->height == 2160) {
            s->level = 6;
            if (avctx->time_base.num == 1001 && avctx->time_base.den == 60000)
                s->base_vf = 17;
            if (avctx->time_base.num == 1 && avctx->time_base.den == 50)
                s->base_vf = 18;
        }
    }

    if (s->interlaced && s->base_vf <= 0) {
        av_log(avctx, AV_LOG_ERROR, "Interlacing not supported with non standard formats!\n");
        return AVERROR_UNKNOWN;
    }

    if (s->interlaced)
        av_log(avctx, AV_LOG_WARNING, "Interlacing enabled!\n");

    if ((s->slice_width  & (s->slice_width  - 1)) ||
        (s->slice_height & (s->slice_height - 1))) {
        av_log(avctx, AV_LOG_ERROR, "Slice size is not a power of two!\n");
        return AVERROR_UNKNOWN;
    }

    if ((s->slice_width > avctx->width) ||
        (s->slice_height > avctx->height)) {
        av_log(avctx, AV_LOG_ERROR, "Slice size is bigger than the image!\n");
        return AVERROR_UNKNOWN;
    }

    if (s->base_vf <= 0) {
        if (avctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
            s->strict_compliance = s->base_vf = 0;
            av_log(avctx, AV_LOG_WARNING, "Disabling strict compliance\n");
        } else {
            av_log(avctx, AV_LOG_WARNING, "Given format does not strictly comply with "
                   "the specifications, please add a -strict -1 flag to use it\n");
            return AVERROR_UNKNOWN;
        }
    } else {
        av_log(avctx, AV_LOG_INFO, "Selected base video format = %i\n", s->base_vf);
    }

    avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift);

    /* Planes initialization */
    for (i = 0; i < 3; i++) {
        int w, h;
        p = &s->plane[i];
        p->width      = avctx->width  >> (i ? s->chroma_x_shift : 0);
        p->height     = avctx->height >> (i ? s->chroma_y_shift : 0);
        if (s->interlaced)
            p->height >>= 1;
        p->dwt_width  = w = FFALIGN(p->width,  (1 << s->wavelet_depth));
        p->dwt_height = h = FFALIGN(p->height, (1 << s->wavelet_depth));
        p->coef_stride = FFALIGN(p->dwt_width, 32);
        p->coef_buf = av_malloc(p->coef_stride*p->dwt_height*sizeof(dwtcoef));
        if (!p->coef_buf)
            goto alloc_fail;
        for (level = s->wavelet_depth-1; level >= 0; level--) {
            w = w >> 1;
            h = h >> 1;
            for (o = 0; o < 4; o++) {
                b = &p->band[level][o];
                b->width  = w;
                b->height = h;
                b->stride = p->coef_stride;
                shift = (o > 1)*b->height*b->stride + (o & 1)*b->width;
                b->buf = p->coef_buf + shift;
            }
        }

        /* DWT init */
        if (ff_vc2enc_init_transforms(&s->transform_args[i].t,
                                      s->plane[i].coef_stride,
                                      s->plane[i].dwt_height,
                                      s->slice_width, s->slice_height))
            goto alloc_fail;
    }

    /* Slices */
    s->num_x = s->plane[0].dwt_width/s->slice_width;
    s->num_y = s->plane[0].dwt_height/s->slice_height;

    s->slice_args = av_malloc(s->num_x*s->num_y*sizeof(SliceArgs));
    if (!s->slice_args)
        goto alloc_fail;

    /* Lookup tables */
    s->coef_lut_len = av_malloc(2*COEF_LUT_TAB*s->q_ceil*sizeof(*s->coef_lut_len));
    if (!s->coef_lut_len)
        goto alloc_fail;

    s->coef_lut_val = av_malloc(2*COEF_LUT_TAB*s->q_ceil*sizeof(*s->coef_lut_val));
    if (!s->coef_lut_val)
        goto alloc_fail;

    for (i = 0; i < s->q_ceil; i++) {
        for (j = -COEF_LUT_TAB; j < COEF_LUT_TAB; j++) {
            uint8_t  *len_lut = &s->coef_lut_len[2*i*COEF_LUT_TAB + COEF_LUT_TAB];
            uint32_t *val_lut = &s->coef_lut_val[2*i*COEF_LUT_TAB + COEF_LUT_TAB];
            coeff_quantize_get(j, ff_dirac_qscale_tab[i], &len_lut[j], &val_lut[j]);
        }
    }

    return 0;

alloc_fail:
    vc2_encode_end(avctx);
    av_log(avctx, AV_LOG_ERROR, "Unable to allocate memory!\n");
    return AVERROR(ENOMEM);

static av_cold int vc2_encode_init(AVCodecContext *avctx)
{
    Plane *p;
    SubBand *b;
    int i, j, level, o, shift;
    VC2EncContext *s = avctx->priv_data;

    s->picture_number = 0;

     
    s->q_ceil    = MAX_QUANT_INDEX;

    s->ver.major = 2;
    s->ver.minor = 0;
    s->profile   = 3;
    s->level     = 3;

    s->base_vf   = -1;
    s->strict_compliance = 1;

     
    s->interlaced = !((avctx->field_order == AV_FIELD_UNKNOWN) ||
                      (avctx->field_order == AV_FIELD_PROGRESSIVE));

    if (avctx->pix_fmt == AV_PIX_FMT_YUV422P10) {
        if (avctx->width == 1280 && avctx->height == 720) {
            s->level = 3;
            if (avctx->time_base.num == 1001 && avctx->time_base.den == 60000)
                s->base_vf = 9;
            if (avctx->time_base.num == 1 && avctx->time_base.den == 50)
                s->base_vf = 10;
        } else if (avctx->width == 1920 && avctx->height == 1080) {
            s->level = 3;
            if (s->interlaced) {
                if (avctx->time_base.num == 1001 && avctx->time_base.den == 30000)
                    s->base_vf = 11;
                if (avctx->time_base.num == 1 && avctx->time_base.den == 50)
                    s->base_vf = 12;
            } else {
                if (avctx->time_base.num == 1001 && avctx->time_base.den == 60000)
                    s->base_vf = 13;
                if (avctx->time_base.num == 1 && avctx->time_base.den == 50)
                    s->base_vf = 14;
                if (avctx->time_base.num == 1001 && avctx->time_base.den == 24000)
                    s->base_vf = 21;
            }
        } else if (avctx->width == 3840 && avctx->height == 2160) {
            s->level = 6;
            if (avctx->time_base.num == 1001 && avctx->time_base.den == 60000)
                s->base_vf = 17;
            if (avctx->time_base.num == 1 && avctx->time_base.den == 50)
                s->base_vf = 18;
        }
    }

    if (s->interlaced && s->base_vf <= 0) {
        av_log(avctx, AV_LOG_ERROR, "Interlacing not supported with non standard formats!\n");
        return AVERROR_UNKNOWN;
    }

    if (s->interlaced)
        av_log(avctx, AV_LOG_WARNING, "Interlacing enabled!\n");

    if ((s->slice_width  & (s->slice_width  - 1)) ||
        (s->slice_height & (s->slice_height - 1))) {
        av_log(avctx, AV_LOG_ERROR, "Slice size is not a power of two!\n");
        return AVERROR_UNKNOWN;
    }

    if ((s->slice_width > avctx->width) ||
        (s->slice_height > avctx->height)) {
        av_log(avctx, AV_LOG_ERROR, "Slice size is bigger than the image!\n");
        return AVERROR_UNKNOWN;
    }

    if (s->base_vf <= 0) {
        if (avctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
            s->strict_compliance = s->base_vf = 0;
            av_log(avctx, AV_LOG_WARNING, "Disabling strict compliance\n");
        } else {
            av_log(avctx, AV_LOG_WARNING, "Given format does not strictly comply with "
                   "the specifications, please add a -strict -1 flag to use it\n");
            return AVERROR_UNKNOWN;
        }
    } else {
        av_log(avctx, AV_LOG_INFO, "Selected base video format = %i\n", s->base_vf);
    }

    avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift);

     
    for (i = 0; i < 3; i++) {
        int w, h;
        p = &s->plane[i];
        p->width      = avctx->width  >> (i ? s->chroma_x_shift : 0);
        p->height     = avctx->height >> (i ? s->chroma_y_shift : 0);
        if (s->interlaced)
            p->height >>= 1;
        p->dwt_width  = w = FFALIGN(p->width,  (1 << s->wavelet_depth));
        p->dwt_height = h = FFALIGN(p->height, (1 << s->wavelet_depth));
        p->coef_stride = FFALIGN(p->dwt_width, 32);
        p->coef_buf = av_malloc(p->coef_stride*p->dwt_height*sizeof(dwtcoef));
        if (!p->coef_buf)
            goto alloc_fail;
        for (level = s->wavelet_depth-1; level >= 0; level--) {
            w = w >> 1;
            h = h >> 1;
            for (o = 0; o < 4; o++) {
                b = &p->band[level][o];
                b->width  = w;
                b->height = h;
                b->stride = p->coef_stride;
                shift = (o > 1)*b->height*b->stride + (o & 1)*b->width;
                b->buf = p->coef_buf + shift;
            }
        }

         
        if (ff_vc2enc_init_transforms(&s->transform_args[i].t,
                                      s->plane[i].coef_stride,
                                      s->plane[i].dwt_height,
                                      s->slice_width, s->slice_height))
            goto alloc_fail;
    }

     
    s->num_x = s->plane[0].dwt_width/s->slice_width;
    s->num_y = s->plane[0].dwt_height/s->slice_height;

    s->slice_args = av_malloc(s->num_x*s->num_y*sizeof(SliceArgs));
    if (!s->slice_args)
        goto alloc_fail;

     
    s->coef_lut_len = av_malloc(2*COEF_LUT_TAB*s->q_ceil*sizeof(*s->coef_lut_len));
    if (!s->coef_lut_len)
        goto alloc_fail;

    s->coef_lut_val = av_malloc(2*COEF_LUT_TAB*s->q_ceil*sizeof(*s->coef_lut_val));
    if (!s->coef_lut_val)
        goto alloc_fail;

    for (i = 0; i < s->q_ceil; i++) {
        for (j = -COEF_LUT_TAB; j < COEF_LUT_TAB; j++) {
            uint8_t  *len_lut = &s->coef_lut_len[2*i*COEF_LUT_TAB + COEF_LUT_TAB];
            uint32_t *val_lut = &s->coef_lut_val[2*i*COEF_LUT_TAB + COEF_LUT_TAB];
            coeff_quantize_get(j, ff_dirac_qscale_tab[i], &len_lut[j], &val_lut[j]);
        }
    }

    return 0;

alloc_fail:
    vc2_encode_end(avctx);
    av_log(avctx, AV_LOG_ERROR, "Unable to allocate memory!\n");
    return AVERROR(ENOMEM);