/*
 * VP9 HW decode acceleration through VA API
 *
 * Copyright (C) 2015 Timo Rothenpieler <timo@rothenpieler.org>
 *
 * 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 "libavutil/pixdesc.h"

#include "hwconfig.h"
#include "vaapi_decode.h"
#include "vp9shared.h"

static VASurfaceID vaapi_vp9_surface_id(const VP9Frame *vf)
{
    if (vf)
        return ff_vaapi_get_surface_id(vf->tf.f);
    else
        return VA_INVALID_SURFACE;
}

static int vaapi_vp9_start_frame(AVCodecContext          *avctx,
                                 av_unused const uint8_t *buffer,
                                 av_unused uint32_t       size)
{
    const VP9SharedContext *h = avctx->priv_data;
    VAAPIDecodePicture *pic = h->frames[CUR_FRAME].hwaccel_picture_private;
    VADecPictureParameterBufferVP9 pic_param;
    const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
    int err, i;

    pic->output_surface = vaapi_vp9_surface_id(&h->frames[CUR_FRAME]);

    pic_param = (VADecPictureParameterBufferVP9) {
        .frame_width                      = avctx->width,
        .frame_height                     = avctx->height,

        .pic_fields.bits = {
            .subsampling_x                = pixdesc->log2_chroma_w,
            .subsampling_y                = pixdesc->log2_chroma_h,
            .frame_type                   = !h->h.keyframe,
            .show_frame                   = !h->h.invisible,
            .error_resilient_mode         = h->h.errorres,
            .intra_only                   = h->h.intraonly,
            .allow_high_precision_mv      = h->h.keyframe ? 0 : h->h.highprecisionmvs,
            .mcomp_filter_type            = h->h.filtermode ^ (h->h.filtermode <= 1),
            .frame_parallel_decoding_mode = h->h.parallelmode,
            .reset_frame_context          = h->h.resetctx,
            .refresh_frame_context        = h->h.refreshctx,
            .frame_context_idx            = h->h.framectxid,

            .segmentation_enabled          = h->h.segmentation.enabled,
            .segmentation_temporal_update  = h->h.segmentation.temporal,
            .segmentation_update_map       = h->h.segmentation.update_map,

            .last_ref_frame                = h->h.refidx[0],
            .last_ref_frame_sign_bias      = h->h.signbias[0],
            .golden_ref_frame              = h->h.refidx[1],
            .golden_ref_frame_sign_bias    = h->h.signbias[1],
            .alt_ref_frame                 = h->h.refidx[2],
            .alt_ref_frame_sign_bias       = h->h.signbias[2],
            .lossless_flag                 = h->h.lossless,
        },

        .filter_level                      = h->h.filter.level,
        .sharpness_level                   = h->h.filter.sharpness,
        .log2_tile_rows                    = h->h.tiling.log2_tile_rows,
        .log2_tile_columns                 = h->h.tiling.log2_tile_cols,

        .frame_header_length_in_bytes      = h->h.uncompressed_header_size,
        .first_partition_size              = h->h.compressed_header_size,

        .profile                           = h->h.profile,
        .bit_depth                         = h->h.bpp,
    };

    for (i = 0; i < 7; i++)
        pic_param.mb_segment_tree_probs[i] = h->h.segmentation.prob[i];

    if (h->h.segmentation.temporal) {
        for (i = 0; i < 3; i++)
            pic_param.segment_pred_probs[i] = h->h.segmentation.pred_prob[i];
    } else {
        memset(pic_param.segment_pred_probs, 255, sizeof(pic_param.segment_pred_probs));
    }

    for (i = 0; i < 8; i++) {
        if (h->refs[i].f->buf[0])
            pic_param.reference_frames[i] = ff_vaapi_get_surface_id(h->refs[i].f);
        else
            pic_param.reference_frames[i] = VA_INVALID_ID;
    }

    err = ff_vaapi_decode_make_param_buffer(avctx, pic,
                                            VAPictureParameterBufferType,
                                            &pic_param, sizeof(pic_param));
    if (err < 0) {
        ff_vaapi_decode_cancel(avctx, pic);
        return err;
    }

    return 0;
}

static int vaapi_vp9_end_frame(AVCodecContext *avctx)
{
    const VP9SharedContext *h = avctx->priv_data;
    VAAPIDecodePicture *pic = h->frames[CUR_FRAME].hwaccel_picture_private;

    return ff_vaapi_decode_issue(avctx, pic);
}

static int vaapi_vp9_decode_slice(AVCodecContext *avctx,
                                  const uint8_t  *buffer,
                                  uint32_t        size)
{
    const VP9SharedContext *h = avctx->priv_data;
    VAAPIDecodePicture *pic = h->frames[CUR_FRAME].hwaccel_picture_private;
    VASliceParameterBufferVP9 slice_param;
    int err, i;

    slice_param = (VASliceParameterBufferVP9) {
        .slice_data_size   = size,
        .slice_data_offset = 0,
        .slice_data_flag   = VA_SLICE_DATA_FLAG_ALL,
    };

    for (i = 0; i < 8; i++) {
        slice_param.seg_param[i] = (VASegmentParameterVP9) {
            .segment_flags.fields = {
                .segment_reference_enabled = h->h.segmentation.feat[i].ref_enabled,
                .segment_reference         = h->h.segmentation.feat[i].ref_val,
                .segment_reference_skipped = h->h.segmentation.feat[i].skip_enabled,
            },

            .luma_dc_quant_scale           = h->h.segmentation.feat[i].qmul[0][0],
            .luma_ac_quant_scale           = h->h.segmentation.feat[i].qmul[0][1],
            .chroma_dc_quant_scale         = h->h.segmentation.feat[i].qmul[1][0],
            .chroma_ac_quant_scale         = h->h.segmentation.feat[i].qmul[1][1],
        };

        memcpy(slice_param.seg_param[i].filter_level, h->h.segmentation.feat[i].lflvl, sizeof(slice_param.seg_param[i].filter_level));
    }

    err = ff_vaapi_decode_make_slice_buffer(avctx, pic,
                                            &slice_param, sizeof(slice_param),
                                            buffer, size);
    if (err) {
        ff_vaapi_decode_cancel(avctx, pic);
        return err;
    }

    return 0;
}

const AVHWAccel ff_vp9_vaapi_hwaccel = {
    .name                 = "vp9_vaapi",
    .type                 = AVMEDIA_TYPE_VIDEO,
    .id                   = AV_CODEC_ID_VP9,
    .pix_fmt              = AV_PIX_FMT_VAAPI,
    .start_frame          = vaapi_vp9_start_frame,
    .end_frame            = vaapi_vp9_end_frame,
    .decode_slice         = vaapi_vp9_decode_slice,
    .frame_priv_data_size = sizeof(VAAPIDecodePicture),
    .init                 = ff_vaapi_decode_init,
    .uninit               = ff_vaapi_decode_uninit,
    .frame_params         = ff_vaapi_common_frame_params,
    .priv_data_size       = sizeof(VAAPIDecodeContext),
    .caps_internal        = HWACCEL_CAP_ASYNC_SAFE,
};
