/*
 * 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 "hwaccel_internal.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)
            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 FFHWAccel ff_vp9_vaapi_hwaccel = {
    .p.name               = "vp9_vaapi",
    .p.type               = AVMEDIA_TYPE_VIDEO,
    .p.id                 = AV_CODEC_ID_VP9,
    .p.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,
};
