/*
 * VC-1 decode acceleration through VDPAU
 *
 * Copyright (c) 2008 NVIDIA
 * Copyright (c) 2013 Rémi Denis-Courmont
 *
 * 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 <vdpau/vdpau.h>

#include "avcodec.h"
#include "hwconfig.h"
#include "vc1.h"
#include "vdpau.h"
#include "vdpau_internal.h"

static int vdpau_vc1_start_frame(AVCodecContext *avctx,
                                 const uint8_t *buffer, uint32_t size)
{
    VC1Context * const v  = avctx->priv_data;
    MpegEncContext * const s = &v->s;
    Picture *pic          = s->current_picture_ptr;
    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
    VdpPictureInfoVC1 *info = &pic_ctx->info.vc1;
    VdpVideoSurface ref;

    /*  fill LvPictureInfoVC1 struct */
    info->forward_reference  = VDP_INVALID_HANDLE;
    info->backward_reference = VDP_INVALID_HANDLE;

    switch (s->pict_type) {
    case AV_PICTURE_TYPE_B:
        if (s->next_picture_ptr) {
        ref = ff_vdpau_get_surface_id(s->next_picture.f);
        assert(ref != VDP_INVALID_HANDLE);
        info->backward_reference = ref;
        }
        /* fall-through */
    case AV_PICTURE_TYPE_P:
        if (s->last_picture_ptr) {
        ref = ff_vdpau_get_surface_id(s->last_picture.f);
        assert(ref != VDP_INVALID_HANDLE);
        info->forward_reference  = ref;
        }
    }

    info->slice_count       = 0;
    if (v->bi_type)
        info->picture_type  = 4;
    else
        info->picture_type  = s->pict_type - 1 + s->pict_type / 3;

    info->frame_coding_mode = v->fcm ? (v->fcm + 1) : 0;
    info->postprocflag      = v->postprocflag;
    info->pulldown          = v->broadcast;
    info->interlace         = v->interlace;
    info->tfcntrflag        = v->tfcntrflag;
    info->finterpflag       = v->finterpflag;
    info->psf               = v->psf;
    info->dquant            = v->dquant;
    info->panscan_flag      = v->panscanflag;
    info->refdist_flag      = v->refdist_flag;
    info->quantizer         = v->quantizer_mode;
    info->extended_mv       = v->extended_mv;
    info->extended_dmv      = v->extended_dmv;
    info->overlap           = v->overlap;
    info->vstransform       = v->vstransform;
    info->loopfilter        = v->s.loop_filter;
    info->fastuvmc          = v->fastuvmc;
    info->range_mapy_flag   = v->range_mapy_flag;
    info->range_mapy        = v->range_mapy;
    info->range_mapuv_flag  = v->range_mapuv_flag;
    info->range_mapuv       = v->range_mapuv;
    /* Specific to simple/main profile only */
    info->multires          = v->multires;
    info->syncmarker        = v->resync_marker;
    info->rangered          = v->rangered | (v->rangeredfrm << 1);
    info->maxbframes        = v->s.max_b_frames;
    info->deblockEnable     = v->postprocflag & 1;
    info->pquant            = v->pq;

    return ff_vdpau_common_start_frame(pic_ctx, buffer, size);
}

static int vdpau_vc1_decode_slice(AVCodecContext *avctx,
                                  const uint8_t *buffer, uint32_t size)
{
    VC1Context * const v  = avctx->priv_data;
    MpegEncContext * const s = &v->s;
    Picture *pic          = s->current_picture_ptr;
    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
    int val;

    val = ff_vdpau_add_buffer(pic_ctx, buffer, size);
    if (val < 0)
        return val;

    pic_ctx->info.vc1.slice_count++;
    return 0;
}

static int vdpau_vc1_init(AVCodecContext *avctx)
{
    VdpDecoderProfile profile;

    switch (avctx->profile) {
    case FF_PROFILE_VC1_SIMPLE:
        profile = VDP_DECODER_PROFILE_VC1_SIMPLE;
        break;
    case FF_PROFILE_VC1_MAIN:
        profile = VDP_DECODER_PROFILE_VC1_MAIN;
        break;
    case FF_PROFILE_VC1_ADVANCED:
        profile = VDP_DECODER_PROFILE_VC1_ADVANCED;
        break;
    default:
        return AVERROR(ENOTSUP);
    }

    return ff_vdpau_common_init(avctx, profile, avctx->level);
}

#if CONFIG_WMV3_VDPAU_HWACCEL
const AVHWAccel ff_wmv3_vdpau_hwaccel = {
    .name           = "wm3_vdpau",
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = AV_CODEC_ID_WMV3,
    .pix_fmt        = AV_PIX_FMT_VDPAU,
    .start_frame    = vdpau_vc1_start_frame,
    .end_frame      = ff_vdpau_mpeg_end_frame,
    .decode_slice   = vdpau_vc1_decode_slice,
    .frame_priv_data_size = sizeof(struct vdpau_picture_context),
    .init           = vdpau_vc1_init,
    .uninit         = ff_vdpau_common_uninit,
    .frame_params   = ff_vdpau_common_frame_params,
    .priv_data_size = sizeof(VDPAUContext),
    .caps_internal  = HWACCEL_CAP_ASYNC_SAFE,
};
#endif

const AVHWAccel ff_vc1_vdpau_hwaccel = {
    .name           = "vc1_vdpau",
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = AV_CODEC_ID_VC1,
    .pix_fmt        = AV_PIX_FMT_VDPAU,
    .start_frame    = vdpau_vc1_start_frame,
    .end_frame      = ff_vdpau_mpeg_end_frame,
    .decode_slice   = vdpau_vc1_decode_slice,
    .frame_priv_data_size = sizeof(struct vdpau_picture_context),
    .init           = vdpau_vc1_init,
    .uninit         = ff_vdpau_common_uninit,
    .frame_params   = ff_vdpau_common_frame_params,
    .priv_data_size = sizeof(VDPAUContext),
    .caps_internal  = HWACCEL_CAP_ASYNC_SAFE,
};
