---
 libavcodec/Makefile                 |  12 +-
 libavcodec/dxva2.c                  | 174 -------------
 libavcodec/dxva2_h264.c             | 475 ------------------------------------
 libavcodec/dxva2_hevc.c             | 381 -----------------------------
 libavcodec/dxva2_internal.h         |  56 -----
 libavcodec/dxva2_mpeg2.c            | 283 ---------------------
 libavcodec/dxva2_vc1.c              | 297 ----------------------
 libavcodec/dxva_h264_template.c     | 475 ++++++++++++++++++++++++++++++++++++
 libavcodec/dxva_hevc_template.c     | 381 +++++++++++++++++++++++++++++
 libavcodec/dxva_internal_template.h |  56 +++++
 libavcodec/dxva_mpeg2_template.c    | 283 +++++++++++++++++++++
 libavcodec/dxva_template.c          | 174 +++++++++++++
 libavcodec/dxva_vc1_template.c      | 297 ++++++++++++++++++++++
 13 files changed, 1672 insertions(+), 1672 deletions(-)
 delete mode 100644 libavcodec/dxva2.c
 delete mode 100644 libavcodec/dxva2_h264.c
 delete mode 100644 libavcodec/dxva2_hevc.c
 delete mode 100644 libavcodec/dxva2_internal.h
 delete mode 100644 libavcodec/dxva2_mpeg2.c
 delete mode 100644 libavcodec/dxva2_vc1.c
 create mode 100644 libavcodec/dxva_h264_template.c
 create mode 100644 libavcodec/dxva_hevc_template.c
 create mode 100644 libavcodec/dxva_internal_template.h
 create mode 100644 libavcodec/dxva_mpeg2_template.c
 create mode 100644 libavcodec/dxva_template.c
 create mode 100644 libavcodec/dxva_vc1_template.c

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index fc8c6e9..0937af9 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -557,25 +557,25 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER)       += adpcm.o 
adpcm_data.o
 OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER)       += adpcmenc.o adpcm_data.o
 
 # hardware accelerators
-OBJS-$(CONFIG_DXVA2)                      += dxva2.o
+OBJS-$(CONFIG_DXVA2)                      += dxva_template.o
 OBJS-$(CONFIG_VAAPI)                      += vaapi.o
 OBJS-$(CONFIG_VDA)                        += vda.o
 OBJS-$(CONFIG_VDPAU)                      += vdpau.o
 
 OBJS-$(CONFIG_H263_VAAPI_HWACCEL)         += vaapi_mpeg4.o
 OBJS-$(CONFIG_H263_VDPAU_HWACCEL)         += vdpau_mpeg4.o
-OBJS-$(CONFIG_H264_DXVA2_HWACCEL)         += dxva2_h264.o
+OBJS-$(CONFIG_H264_DXVA2_HWACCEL)         += dxva_h264_template.o
 OBJS-$(CONFIG_H264_VAAPI_HWACCEL)         += vaapi_h264.o
 OBJS-$(CONFIG_H264_VDA_HWACCEL)           += vda_h264.o
 OBJS-$(CONFIG_H264_VDPAU_HWACCEL)         += vdpau_h264.o
-OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL)         += dxva2_hevc.o
+OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL)         += dxva_hevc_template.o
 OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL)        += vdpau_mpeg12.o
-OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL)        += dxva2_mpeg2.o
+OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL)        += dxva_mpeg2_template.o
 OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL)        += vaapi_mpeg2.o
 OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL)        += vdpau_mpeg12.o
 OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL)        += vaapi_mpeg4.o
 OBJS-$(CONFIG_MPEG4_VDPAU_HWACCEL)        += vdpau_mpeg4.o
-OBJS-$(CONFIG_VC1_DXVA2_HWACCEL)          += dxva2_vc1.o
+OBJS-$(CONFIG_VC1_DXVA2_HWACCEL)          += dxva_vc1_template.o
 OBJS-$(CONFIG_VC1_VAAPI_HWACCEL)          += vaapi_vc1.o
 OBJS-$(CONFIG_VC1_VDPAU_HWACCEL)          += vdpau_vc1.o
 
@@ -723,7 +723,7 @@ SKIPHEADERS                            += %_tablegen.h      
            \
                                           tableprint.h                  \
                                           $(ARCH)/vp56_arith.h          \
 
-SKIPHEADERS-$(CONFIG_DXVA2)            += dxva2.h dxva2_internal.h
+SKIPHEADERS-$(CONFIG_DXVA2)            += dxva2.h dxva2_internal_template.h
 SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER)  += libschroedinger.h
 SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h
 SKIPHEADERS-$(CONFIG_QSV)              += qsv.h qsv_internal.h
diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
deleted file mode 100644
index 9ee22c8..0000000
--- a/libavcodec/dxva2.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * DXVA2 HW acceleration.
- *
- * copyright (c) 2010 Laurent Aimar
- *
- * This file is part of Libav.
- *
- * Libav 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.
- *
- * Libav 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 Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include "libavutil/log.h"
-#include "libavutil/time.h"
-
-#include "avcodec.h"
-#include "mpegvideo.h"
-#include "dxva2_internal.h"
-
-void *ff_dxva2_get_surface(const AVFrame *frame)
-{
-    return frame->data[3];
-}
-
-unsigned ff_dxva2_get_surface_index(const struct dxva_context *ctx,
-                                    const AVFrame *frame)
-{
-    void *surface = ff_dxva2_get_surface(frame);
-    unsigned i;
-
-    for (i = 0; i < ctx->surface_count; i++)
-        if (ctx->surface[i] == surface)
-            return i;
-
-    assert(0);
-    return 0;
-}
-
-int ff_dxva2_commit_buffer(AVCodecContext *avctx,
-                           struct dxva_context *ctx,
-                           DXVA2_DecodeBufferDesc *dsc,
-                           unsigned type, const void *data, unsigned size,
-                           unsigned mb_count)
-{
-    void     *dxva_data;
-    unsigned dxva_size;
-    int      result;
-    HRESULT hr;
-
-    hr = IDirectXVideoDecoder_GetBuffer(ctx->decoder, type,
-                                        &dxva_data, &dxva_size);
-    if (FAILED(hr)) {
-        av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %u: 0x%lx\n",
-               type, hr);
-        return -1;
-    }
-    if (size <= dxva_size) {
-        memcpy(dxva_data, data, size);
-
-        memset(dsc, 0, sizeof(*dsc));
-        dsc->CompressedBufferType = type;
-        dsc->DataSize             = size;
-        dsc->NumMBsInBuffer       = mb_count;
-
-        result = 0;
-    } else {
-        av_log(avctx, AV_LOG_ERROR, "Buffer for type %u was too small\n", 
type);
-        result = -1;
-    }
-
-    hr = IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, type);
-    if (FAILED(hr)) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Failed to release buffer type %u: 0x%lx\n",
-               type, hr);
-        result = -1;
-    }
-    return result;
-}
-
-int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
-                              const void *pp, unsigned pp_size,
-                              const void *qm, unsigned qm_size,
-                              int (*commit_bs_si)(AVCodecContext *,
-                                                  DXVA2_DecodeBufferDesc *bs,
-                                                  DXVA2_DecodeBufferDesc 
*slice))
-{
-    struct dxva_context *ctx = avctx->hwaccel_context;
-    unsigned               buffer_count = 0;
-    DXVA2_DecodeBufferDesc buffer[4];
-    DXVA2_DecodeExecuteParams exec = { 0 };
-    int result, runs = 0;
-    HRESULT hr;
-
-    do {
-        hr = IDirectXVideoDecoder_BeginFrame(ctx->decoder,
-                                             ff_dxva2_get_surface(frame),
-                                             NULL);
-        if (hr == E_PENDING)
-            av_usleep(2000);
-    } while (hr == E_PENDING && ++runs < 50);
-
-    if (FAILED(hr)) {
-        av_log(avctx, AV_LOG_ERROR, "Failed to begin frame: 0x%lx\n", hr);
-        return -1;
-    }
-
-    result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
-                                    DXVA2_PictureParametersBufferType,
-                                    pp, pp_size, 0);
-    if (result) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Failed to add picture parameter buffer\n");
-        goto end;
-    }
-    buffer_count++;
-
-    if (qm_size > 0) {
-        result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
-                                        
DXVA2_InverseQuantizationMatrixBufferType,
-                                        qm, qm_size, 0);
-        if (result) {
-            av_log(avctx, AV_LOG_ERROR,
-                   "Failed to add inverse quantization matrix buffer\n");
-            goto end;
-        }
-        buffer_count++;
-    }
-
-    result = commit_bs_si(avctx,
-                          &buffer[buffer_count + 0],
-                          &buffer[buffer_count + 1]);
-    if (result) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Failed to add bitstream or slice control buffer\n");
-        goto end;
-    }
-    buffer_count += 2;
-
-    /* TODO Film Grain when possible */
-
-    assert(buffer_count == 1 + (qm_size > 0) + 2);
-
-    exec.NumCompBuffers      = buffer_count;
-    exec.pCompressedBuffers  = buffer;
-    exec.pExtensionData      = NULL;
-    hr = IDirectXVideoDecoder_Execute(ctx->decoder, &exec);
-    if (FAILED(hr)) {
-        av_log(avctx, AV_LOG_ERROR, "Failed to execute: 0x%lx\n", hr);
-        result = -1;
-    }
-
-end:
-    hr = IDirectXVideoDecoder_EndFrame(ctx->decoder, NULL);
-    if (FAILED(hr)) {
-        av_log(avctx, AV_LOG_ERROR, "Failed to end frame: 0x%lx\n", hr);
-        result = -1;
-    }
-
-    return result;
-}
diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c
deleted file mode 100644
index a5e9705..0000000
--- a/libavcodec/dxva2_h264.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * DXVA2 H264 HW acceleration.
- *
- * copyright (c) 2009 Laurent Aimar
- *
- * This file is part of Libav.
- *
- * Libav 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.
- *
- * Libav 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 Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "dxva2_internal.h"
-#include "h264.h"
-#include "h264data.h"
-#include "mpegutils.h"
-
-struct dxva2_picture_context {
-    DXVA_PicParams_H264   pp;
-    DXVA_Qmatrix_H264     qm;
-    unsigned              slice_count;
-    DXVA_Slice_H264_Short slice_short[MAX_SLICES];
-    DXVA_Slice_H264_Long  slice_long[MAX_SLICES];
-    const uint8_t         *bitstream;
-    unsigned              bitstream_size;
-};
-
-static void fill_picture_entry(DXVA_PicEntry_H264 *pic,
-                               unsigned index, unsigned flag)
-{
-    assert((index&0x7f) == index && (flag&0x01) == flag);
-    pic->bPicEntry = index | (flag << 7);
-}
-
-static void fill_picture_parameters(struct dxva_context *ctx, const 
H264Context *h,
-                                    DXVA_PicParams_H264 *pp)
-{
-    const H264Picture *current_picture = h->cur_pic_ptr;
-    int i, j;
-
-    memset(pp, 0, sizeof(*pp));
-    /* Configure current picture */
-    fill_picture_entry(&pp->CurrPic,
-                       ff_dxva2_get_surface_index(ctx, current_picture->f),
-                       h->picture_structure == PICT_BOTTOM_FIELD);
-    /* Configure the set of references */
-    pp->UsedForReferenceFlags  = 0;
-    pp->NonExistingFrameFlags  = 0;
-    for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->RefFrameList); i++) {
-        const H264Picture *r;
-        if (j < h->short_ref_count) {
-            r = h->short_ref[j++];
-        } else {
-            r = NULL;
-            while (!r && j < h->short_ref_count + 16)
-                r = h->long_ref[j++ - h->short_ref_count];
-        }
-        if (r) {
-            fill_picture_entry(&pp->RefFrameList[i],
-                               ff_dxva2_get_surface_index(ctx, r->f),
-                               r->long_ref != 0);
-
-            if ((r->reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX)
-                pp->FieldOrderCntList[i][0] = r->field_poc[0];
-            if ((r->reference & PICT_BOTTOM_FIELD) && r->field_poc[1] != 
INT_MAX)
-                pp->FieldOrderCntList[i][1] = r->field_poc[1];
-
-            pp->FrameNumList[i] = r->long_ref ? r->pic_id : r->frame_num;
-            if (r->reference & PICT_TOP_FIELD)
-                pp->UsedForReferenceFlags |= 1 << (2*i + 0);
-            if (r->reference & PICT_BOTTOM_FIELD)
-                pp->UsedForReferenceFlags |= 1 << (2*i + 1);
-        } else {
-            pp->RefFrameList[i].bPicEntry = 0xff;
-            pp->FieldOrderCntList[i][0]   = 0;
-            pp->FieldOrderCntList[i][1]   = 0;
-            pp->FrameNumList[i]           = 0;
-        }
-    }
-
-    pp->wFrameWidthInMbsMinus1        = h->mb_width  - 1;
-    pp->wFrameHeightInMbsMinus1       = h->mb_height - 1;
-    pp->num_ref_frames                = h->sps.ref_frame_count;
-
-    pp->wBitFields                    = ((h->picture_structure != PICT_FRAME) 
<<  0) |
-                                        ((h->sps.mb_aff &&
-                                        (h->picture_structure == PICT_FRAME)) 
<<  1) |
-                                        (h->sps.residual_color_transform_flag 
<<  2) |
-                                        /* sp_for_switch_flag (not implemented 
by Libav) */
-                                        (0                                    
<<  3) |
-                                        (h->sps.chroma_format_idc             
<<  4) |
-                                        ((h->nal_ref_idc != 0)                
<<  6) |
-                                        (h->pps.constrained_intra_pred        
<<  7) |
-                                        (h->pps.weighted_pred                 
<<  8) |
-                                        (h->pps.weighted_bipred_idc           
<<  9) |
-                                        /* MbsConsecutiveFlag */
-                                        (1                                    
<< 11) |
-                                        (h->sps.frame_mbs_only_flag           
<< 12) |
-                                        (h->pps.transform_8x8_mode            
<< 13) |
-                                        ((h->sps.level_idc >= 31)             
<< 14) |
-                                        /* IntraPicFlag (Modified if we detect 
a non
-                                         * intra slice in 
dxva2_h264_decode_slice) */
-                                        (1                                    
<< 15);
-
-    pp->bit_depth_luma_minus8         = h->sps.bit_depth_luma - 8;
-    pp->bit_depth_chroma_minus8       = h->sps.bit_depth_chroma - 8;
-    if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG)
-        pp->Reserved16Bits            = 0;
-    else if (ctx->workaround & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO)
-        pp->Reserved16Bits            = 0x34c;
-    else
-        pp->Reserved16Bits            = 3; /* FIXME is there a way to detect 
the right mode ? */
-    pp->StatusReportFeedbackNumber    = 1 + ctx->report_id++;
-    pp->CurrFieldOrderCnt[0] = 0;
-    if ((h->picture_structure & PICT_TOP_FIELD) &&
-        current_picture->field_poc[0] != INT_MAX)
-        pp->CurrFieldOrderCnt[0] = current_picture->field_poc[0];
-    pp->CurrFieldOrderCnt[1] = 0;
-    if ((h->picture_structure & PICT_BOTTOM_FIELD) &&
-        current_picture->field_poc[1] != INT_MAX)
-        pp->CurrFieldOrderCnt[1] = current_picture->field_poc[1];
-    pp->pic_init_qs_minus26           = h->pps.init_qs - 26;
-    pp->chroma_qp_index_offset        = h->pps.chroma_qp_index_offset[0];
-    pp->second_chroma_qp_index_offset = h->pps.chroma_qp_index_offset[1];
-    pp->ContinuationFlag              = 1;
-    pp->pic_init_qp_minus26           = h->pps.init_qp - 26;
-    pp->num_ref_idx_l0_active_minus1  = h->pps.ref_count[0] - 1;
-    pp->num_ref_idx_l1_active_minus1  = h->pps.ref_count[1] - 1;
-    pp->Reserved8BitsA                = 0;
-    pp->frame_num                     = h->frame_num;
-    pp->log2_max_frame_num_minus4     = h->sps.log2_max_frame_num - 4;
-    pp->pic_order_cnt_type            = h->sps.poc_type;
-    if (h->sps.poc_type == 0)
-        pp->log2_max_pic_order_cnt_lsb_minus4 = h->sps.log2_max_poc_lsb - 4;
-    else if (h->sps.poc_type == 1)
-        pp->delta_pic_order_always_zero_flag = 
h->sps.delta_pic_order_always_zero_flag;
-    pp->direct_8x8_inference_flag     = h->sps.direct_8x8_inference_flag;
-    pp->entropy_coding_mode_flag      = h->pps.cabac;
-    pp->pic_order_present_flag        = h->pps.pic_order_present;
-    pp->num_slice_groups_minus1       = h->pps.slice_group_count - 1;
-    pp->slice_group_map_type          = h->pps.mb_slice_group_map_type;
-    pp->deblocking_filter_control_present_flag = 
h->pps.deblocking_filter_parameters_present;
-    pp->redundant_pic_cnt_present_flag= h->pps.redundant_pic_cnt_present;
-    pp->Reserved8BitsB                = 0;
-    pp->slice_group_change_rate_minus1= 0;  /* XXX not implemented by Libav */
-    //pp->SliceGroupMap[810];               /* XXX not implemented by Libav */
-}
-
-static void fill_scaling_lists(struct dxva_context *ctx, const H264Context *h, 
DXVA_Qmatrix_H264 *qm)
-{
-    unsigned i, j;
-    memset(qm, 0, sizeof(*qm));
-    if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) {
-        for (i = 0; i < 6; i++)
-            for (j = 0; j < 16; j++)
-                qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][j];
-
-        for (i = 0; i < 64; i++) {
-            qm->bScalingLists8x8[0][i] = h->pps.scaling_matrix8[0][i];
-            qm->bScalingLists8x8[1][i] = h->pps.scaling_matrix8[3][i];
-        }
-    } else {
-        for (i = 0; i < 6; i++)
-            for (j = 0; j < 16; j++)
-                qm->bScalingLists4x4[i][j] = 
h->pps.scaling_matrix4[i][zigzag_scan[j]];
-
-        for (i = 0; i < 64; i++) {
-            qm->bScalingLists8x8[0][i] = 
h->pps.scaling_matrix8[0][ff_zigzag_direct[i]];
-            qm->bScalingLists8x8[1][i] = 
h->pps.scaling_matrix8[3][ff_zigzag_direct[i]];
-        }
-    }
-}
-
-static int is_slice_short(struct dxva_context *ctx)
-{
-    assert(ctx->cfg->ConfigBitstreamRaw == 1 ||
-           ctx->cfg->ConfigBitstreamRaw == 2);
-    return ctx->cfg->ConfigBitstreamRaw == 2;
-}
-
-static void fill_slice_short(DXVA_Slice_H264_Short *slice,
-                             unsigned position, unsigned size)
-{
-    memset(slice, 0, sizeof(*slice));
-    slice->BSNALunitDataLocation = position;
-    slice->SliceBytesInBuffer    = size;
-    slice->wBadSliceChopping     = 0;
-}
-
-static int get_refpic_index(const DXVA_PicParams_H264 *pp, int surface_index)
-{
-    int i;
-    for (i = 0; i < FF_ARRAY_ELEMS(pp->RefFrameList); i++) {
-        if ((pp->RefFrameList[i].bPicEntry & 0x7f) == surface_index)
-          return i;
-    }
-    return 0x7f;
-}
-
-static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
-                            const DXVA_PicParams_H264 *pp, unsigned position, 
unsigned size)
-{
-    const H264Context *h = avctx->priv_data;
-    H264SliceContext *sl = &h->slice_ctx[0];
-    struct dxva_context *ctx = avctx->hwaccel_context;
-    unsigned list;
-
-    memset(slice, 0, sizeof(*slice));
-    slice->BSNALunitDataLocation = position;
-    slice->SliceBytesInBuffer    = size;
-    slice->wBadSliceChopping     = 0;
-
-    slice->first_mb_in_slice     = (sl->mb_y >> FIELD_OR_MBAFF_PICTURE(h)) * 
h->mb_width + sl->mb_x;
-    slice->NumMbsForSlice        = 0; /* XXX it is set once we have all slices 
*/
-    slice->BitOffsetToSliceData  = get_bits_count(&sl->gb);
-    slice->slice_type            = ff_h264_get_slice_type(sl);
-    if (sl->slice_type_fixed)
-        slice->slice_type += 5;
-    slice->luma_log2_weight_denom       = sl->luma_log2_weight_denom;
-    slice->chroma_log2_weight_denom     = sl->chroma_log2_weight_denom;
-    if (sl->list_count > 0)
-        slice->num_ref_idx_l0_active_minus1 = sl->ref_count[0] - 1;
-    if (sl->list_count > 1)
-        slice->num_ref_idx_l1_active_minus1 = sl->ref_count[1] - 1;
-    slice->slice_alpha_c0_offset_div2   = sl->slice_alpha_c0_offset / 2;
-    slice->slice_beta_offset_div2       = sl->slice_beta_offset     / 2;
-    slice->Reserved8Bits                = 0;
-
-    for (list = 0; list < 2; list++) {
-        unsigned i;
-        for (i = 0; i < FF_ARRAY_ELEMS(slice->RefPicList[list]); i++) {
-            if (list < sl->list_count && i < sl->ref_count[list]) {
-                const H264Picture *r = sl->ref_list[list][i].parent;
-                unsigned plane;
-                unsigned index;
-                if (ctx->workaround & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO)
-                    index = ff_dxva2_get_surface_index(ctx, r->f);
-                else
-                    index = get_refpic_index(pp, 
ff_dxva2_get_surface_index(ctx, r->f));
-                fill_picture_entry(&slice->RefPicList[list][i], index,
-                                   r->reference == PICT_BOTTOM_FIELD);
-                for (plane = 0; plane < 3; plane++) {
-                    int w, o;
-                    if (plane == 0 && sl->luma_weight_flag[list]) {
-                        w = sl->luma_weight[i][list][0];
-                        o = sl->luma_weight[i][list][1];
-                    } else if (plane >= 1 && sl->chroma_weight_flag[list]) {
-                        w = sl->chroma_weight[i][list][plane-1][0];
-                        o = sl->chroma_weight[i][list][plane-1][1];
-                    } else {
-                        w = 1 << (plane == 0 ? sl->luma_log2_weight_denom :
-                                               sl->chroma_log2_weight_denom);
-                        o = 0;
-                    }
-                    slice->Weights[list][i][plane][0] = w;
-                    slice->Weights[list][i][plane][1] = o;
-                }
-            } else {
-                unsigned plane;
-                slice->RefPicList[list][i].bPicEntry = 0xff;
-                for (plane = 0; plane < 3; plane++) {
-                    slice->Weights[list][i][plane][0] = 0;
-                    slice->Weights[list][i][plane][1] = 0;
-                }
-            }
-        }
-    }
-    slice->slice_qs_delta    = 0; /* XXX not implemented by Libav */
-    slice->slice_qp_delta    = sl->qscale - h->pps.init_qp;
-    slice->redundant_pic_cnt = sl->redundant_pic_count;
-    if (sl->slice_type == AV_PICTURE_TYPE_B)
-        slice->direct_spatial_mv_pred_flag = sl->direct_spatial_mv_pred;
-    slice->cabac_init_idc = h->pps.cabac ? sl->cabac_init_idc : 0;
-    if (sl->deblocking_filter < 2)
-        slice->disable_deblocking_filter_idc = 1 - sl->deblocking_filter;
-    else
-        slice->disable_deblocking_filter_idc = sl->deblocking_filter;
-    slice->slice_id = h->current_slice - 1;
-}
-
-static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
-                                             DXVA2_DecodeBufferDesc *bs,
-                                             DXVA2_DecodeBufferDesc *sc)
-{
-    const H264Context *h = avctx->priv_data;
-    const unsigned mb_count = h->mb_width * h->mb_height;
-    struct dxva_context *ctx = avctx->hwaccel_context;
-    const H264Picture *current_picture = h->cur_pic_ptr;
-    struct dxva2_picture_context *ctx_pic = 
current_picture->hwaccel_picture_private;
-    DXVA_Slice_H264_Short *slice = NULL;
-    void     *dxva_data_ptr;
-    uint8_t  *dxva_data, *current, *end;
-    unsigned dxva_size;
-    void     *slice_data;
-    unsigned slice_size;
-    unsigned padding;
-    unsigned i;
-
-    /* Create an annex B bitstream buffer with only slice NAL and finalize 
slice */
-    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
-                                              DXVA2_BitStreamDateBufferType,
-                                              &dxva_data_ptr, &dxva_size)))
-        return -1;
-
-    dxva_data = dxva_data_ptr;
-    current = dxva_data;
-    end = dxva_data + dxva_size;
-
-    for (i = 0; i < ctx_pic->slice_count; i++) {
-        static const uint8_t start_code[] = { 0, 0, 1 };
-        static const unsigned start_code_size = sizeof(start_code);
-        unsigned position, size;
-
-        assert(offsetof(DXVA_Slice_H264_Short, BSNALunitDataLocation) ==
-               offsetof(DXVA_Slice_H264_Long,  BSNALunitDataLocation));
-        assert(offsetof(DXVA_Slice_H264_Short, SliceBytesInBuffer) ==
-               offsetof(DXVA_Slice_H264_Long,  SliceBytesInBuffer));
-
-        if (is_slice_short(ctx))
-            slice = &ctx_pic->slice_short[i];
-        else
-            slice = (DXVA_Slice_H264_Short*)&ctx_pic->slice_long[i];
-
-        position = slice->BSNALunitDataLocation;
-        size     = slice->SliceBytesInBuffer;
-        if (start_code_size + size > end - current) {
-            av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream");
-            break;
-        }
-
-        slice->BSNALunitDataLocation = current - dxva_data;
-        slice->SliceBytesInBuffer    = start_code_size + size;
-
-        if (!is_slice_short(ctx)) {
-            DXVA_Slice_H264_Long *slice_long = (DXVA_Slice_H264_Long*)slice;
-            if (i < ctx_pic->slice_count - 1)
-                slice_long->NumMbsForSlice =
-                    slice_long[1].first_mb_in_slice - 
slice_long[0].first_mb_in_slice;
-            else
-                slice_long->NumMbsForSlice = mb_count - 
slice_long->first_mb_in_slice;
-        }
-
-        memcpy(current, start_code, start_code_size);
-        current += start_code_size;
-
-        memcpy(current, &ctx_pic->bitstream[position], size);
-        current += size;
-    }
-    padding = FFMIN(128 - ((current - dxva_data) & 127), end - current);
-    if (slice && padding > 0) {
-        memset(current, 0, padding);
-        current += padding;
-
-        slice->SliceBytesInBuffer += padding;
-    }
-    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
-                                                  
DXVA2_BitStreamDateBufferType)))
-        return -1;
-    if (i < ctx_pic->slice_count)
-        return -1;
-
-    memset(bs, 0, sizeof(*bs));
-    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
-    bs->DataSize             = current - dxva_data;
-    bs->NumMBsInBuffer       = mb_count;
-
-    if (is_slice_short(ctx)) {
-        slice_data = ctx_pic->slice_short;
-        slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short);
-    } else {
-        slice_data = ctx_pic->slice_long;
-        slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_long);
-    }
-    assert((bs->DataSize & 127) == 0);
-    return ff_dxva2_commit_buffer(avctx, ctx, sc,
-                                  DXVA2_SliceControlBufferType,
-                                  slice_data, slice_size, mb_count);
-}
-
-
-static int dxva2_h264_start_frame(AVCodecContext *avctx,
-                                  av_unused const uint8_t *buffer,
-                                  av_unused uint32_t size)
-{
-    const H264Context *h = avctx->priv_data;
-    struct dxva_context *ctx = avctx->hwaccel_context;
-    struct dxva2_picture_context *ctx_pic = 
h->cur_pic_ptr->hwaccel_picture_private;
-
-    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
-        return -1;
-    assert(ctx_pic);
-
-    /* Fill up DXVA_PicParams_H264 */
-    fill_picture_parameters(ctx, h, &ctx_pic->pp);
-
-    /* Fill up DXVA_Qmatrix_H264 */
-    fill_scaling_lists(ctx, h, &ctx_pic->qm);
-
-    ctx_pic->slice_count    = 0;
-    ctx_pic->bitstream_size = 0;
-    ctx_pic->bitstream      = NULL;
-    return 0;
-}
-
-static int dxva2_h264_decode_slice(AVCodecContext *avctx,
-                                   const uint8_t *buffer,
-                                   uint32_t size)
-{
-    const H264Context *h = avctx->priv_data;
-    const H264SliceContext *sl = &h->slice_ctx[0];
-    struct dxva_context *ctx = avctx->hwaccel_context;
-    const H264Picture *current_picture = h->cur_pic_ptr;
-    struct dxva2_picture_context *ctx_pic = 
current_picture->hwaccel_picture_private;
-    unsigned position;
-
-    if (ctx_pic->slice_count >= MAX_SLICES)
-        return -1;
-
-    if (!ctx_pic->bitstream)
-        ctx_pic->bitstream = buffer;
-    ctx_pic->bitstream_size += size;
-
-    position = buffer - ctx_pic->bitstream;
-    if (is_slice_short(ctx))
-        fill_slice_short(&ctx_pic->slice_short[ctx_pic->slice_count],
-                         position, size);
-    else
-        fill_slice_long(avctx, &ctx_pic->slice_long[ctx_pic->slice_count],
-                        &ctx_pic->pp, position, size);
-    ctx_pic->slice_count++;
-
-    if (sl->slice_type != AV_PICTURE_TYPE_I && sl->slice_type != 
AV_PICTURE_TYPE_SI)
-        ctx_pic->pp.wBitFields &= ~(1 << 15); /* Set IntraPicFlag to 0 */
-    return 0;
-}
-
-static int dxva2_h264_end_frame(AVCodecContext *avctx)
-{
-    H264Context *h = avctx->priv_data;
-    H264SliceContext *sl = &h->slice_ctx[0];
-    struct dxva2_picture_context *ctx_pic =
-        h->cur_pic_ptr->hwaccel_picture_private;
-    int ret;
-
-    if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
-        return -1;
-    ret = ff_dxva2_common_end_frame(avctx, h->cur_pic_ptr->f,
-                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
-                                    &ctx_pic->qm, sizeof(ctx_pic->qm),
-                                    commit_bitstream_and_slice_buffer);
-    if (!ret)
-        ff_h264_draw_horiz_band(h, sl, 0, h->avctx->height);
-    return ret;
-}
-
-AVHWAccel ff_h264_dxva2_hwaccel = {
-    .name           = "h264_dxva2",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_H264,
-    .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
-    .start_frame    = dxva2_h264_start_frame,
-    .decode_slice   = dxva2_h264_decode_slice,
-    .end_frame      = dxva2_h264_end_frame,
-    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
-};
diff --git a/libavcodec/dxva2_hevc.c b/libavcodec/dxva2_hevc.c
deleted file mode 100644
index 257bee7..0000000
--- a/libavcodec/dxva2_hevc.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * DXVA2 HEVC HW acceleration.
- *
- * copyright (c) 2014 - 2015 Hendrik Leppkes
- *
- * This file is part of Libav.
- *
- * Libav 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.
- *
- * Libav 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 Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "libavutil/avassert.h"
-
-#include "dxva2_internal.h"
-#include "hevc.h"
-
-#define MAX_SLICES 256
-
-struct hevc_dxva2_picture_context {
-    DXVA_PicParams_HEVC   pp;
-    DXVA_Qmatrix_HEVC     qm;
-    unsigned              slice_count;
-    DXVA_Slice_HEVC_Short slice_short[MAX_SLICES];
-    const uint8_t         *bitstream;
-    unsigned              bitstream_size;
-};
-
-static void fill_picture_entry(DXVA_PicEntry_HEVC *pic,
-                               unsigned index, unsigned flag)
-{
-    av_assert0((index & 0x7f) == index && (flag & 0x01) == flag);
-    pic->bPicEntry = index | (flag << 7);
-}
-
-static int get_refpic_index(const DXVA_PicParams_HEVC *pp, int surface_index)
-{
-    int i;
-    for (i = 0; i < FF_ARRAY_ELEMS(pp->RefPicList); i++) {
-        if ((pp->RefPicList[i].bPicEntry & 0x7f) == surface_index)
-          return i;
-    }
-    return 0xff;
-}
-
-static void fill_picture_parameters(struct dxva_context *ctx, const 
HEVCContext *h,
-                                    DXVA_PicParams_HEVC *pp)
-{
-    const HEVCFrame *current_picture = h->ref;
-    int i, j, k;
-
-    memset(pp, 0, sizeof(*pp));
-
-    pp->PicWidthInMinCbsY  = h->sps->min_cb_width;
-    pp->PicHeightInMinCbsY = h->sps->min_cb_height;
-
-    pp->wFormatAndSequenceInfoFlags = (h->sps->chroma_format_idc          <<  
0) |
-                                      (h->sps->separate_colour_plane_flag <<  
2) |
-                                      ((h->sps->bit_depth - 8)            <<  
3) |
-                                      ((h->sps->bit_depth - 8)            <<  
6) |
-                                      ((h->sps->log2_max_poc_lsb - 4)     <<  
9) |
-                                      (0                                  << 
13) |
-                                      (0                                  << 
14) |
-                                      (0                                  << 
15);
-
-    fill_picture_entry(&pp->CurrPic, ff_dxva2_get_surface_index(ctx, 
current_picture->frame), 0);
-
-    pp->sps_max_dec_pic_buffering_minus1         = 
h->sps->temporal_layer[h->sps->max_sub_layers - 1].max_dec_pic_buffering - 1;
-    pp->log2_min_luma_coding_block_size_minus3   = h->sps->log2_min_cb_size - 
3;
-    pp->log2_diff_max_min_luma_coding_block_size = 
h->sps->log2_diff_max_min_coding_block_size;
-    pp->log2_min_transform_block_size_minus2     = h->sps->log2_min_tb_size - 
2;
-    pp->log2_diff_max_min_transform_block_size   = h->sps->log2_max_trafo_size 
 - h->sps->log2_min_tb_size;
-    pp->max_transform_hierarchy_depth_inter      = 
h->sps->max_transform_hierarchy_depth_inter;
-    pp->max_transform_hierarchy_depth_intra      = 
h->sps->max_transform_hierarchy_depth_intra;
-    pp->num_short_term_ref_pic_sets              = h->sps->nb_st_rps;
-    pp->num_long_term_ref_pics_sps               = 
h->sps->num_long_term_ref_pics_sps;
-
-    pp->num_ref_idx_l0_default_active_minus1     = 
h->pps->num_ref_idx_l0_default_active - 1;
-    pp->num_ref_idx_l1_default_active_minus1     = 
h->pps->num_ref_idx_l1_default_active - 1;
-    pp->init_qp_minus26                          = h->pps->pic_init_qp_minus26;
-
-    if (h->sh.short_term_ref_pic_set_sps_flag == 0 && h->sh.short_term_rps) {
-        pp->ucNumDeltaPocsOfRefRpsIdx            = 
h->sh.short_term_rps->num_delta_pocs;
-        pp->wNumBitsForShortTermRPSInSlice       = 
h->sh.short_term_ref_pic_set_size;
-    }
-
-    pp->dwCodingParamToolFlags = (h->sps->scaling_list_enable_flag             
  <<  0) |
-                                 (h->sps->amp_enabled_flag                     
  <<  1) |
-                                 (h->sps->sao_enabled                          
  <<  2) |
-                                 (h->sps->pcm_enabled_flag                     
  <<  3) |
-                                 ((h->sps->pcm_enabled_flag ? 
(h->sps->pcm.bit_depth - 1) : 0)            <<  4) |
-                                 ((h->sps->pcm_enabled_flag ? 
(h->sps->pcm.bit_depth_chroma - 1) : 0)     <<  8) |
-                                 ((h->sps->pcm_enabled_flag ? 
(h->sps->pcm.log2_min_pcm_cb_size - 3) : 0) << 12) |
-                                 ((h->sps->pcm_enabled_flag ? 
(h->sps->pcm.log2_max_pcm_cb_size - h->sps->pcm.log2_min_pcm_cb_size) : 0) << 
14) |
-                                 (h->sps->pcm.loop_filter_disable_flag         
  << 16) |
-                                 (h->sps->long_term_ref_pics_present_flag      
  << 17) |
-                                 (h->sps->sps_temporal_mvp_enabled_flag        
  << 18) |
-                                 
(h->sps->sps_strong_intra_smoothing_enable_flag << 19) |
-                                 
(h->pps->dependent_slice_segments_enabled_flag  << 20) |
-                                 (h->pps->output_flag_present_flag             
  << 21) |
-                                 (h->pps->num_extra_slice_header_bits          
  << 22) |
-                                 (h->pps->sign_data_hiding_flag                
  << 25) |
-                                 (h->pps->cabac_init_present_flag              
  << 26) |
-                                 (0                                            
  << 27);
-
-    pp->dwCodingSettingPicturePropertyFlags = 
(h->pps->constrained_intra_pred_flag                <<  0) |
-                                              
(h->pps->transform_skip_enabled_flag                <<  1) |
-                                              
(h->pps->cu_qp_delta_enabled_flag                   <<  2) |
-                                              
(h->pps->pic_slice_level_chroma_qp_offsets_present_flag <<  3) |
-                                              (h->pps->weighted_pred_flag      
                   <<  4) |
-                                              (h->pps->weighted_bipred_flag    
                   <<  5) |
-                                              
(h->pps->transquant_bypass_enable_flag              <<  6) |
-                                              (h->pps->tiles_enabled_flag      
                   <<  7) |
-                                              
(h->pps->entropy_coding_sync_enabled_flag           <<  8) |
-                                              (h->pps->uniform_spacing_flag    
                   <<  9) |
-                                              ((h->pps->tiles_enabled_flag ? 
h->pps->loop_filter_across_tiles_enabled_flag : 0) << 10) |
-                                              
(h->pps->seq_loop_filter_across_slices_enabled_flag << 11) |
-                                              
(h->pps->deblocking_filter_override_enabled_flag    << 12) |
-                                              (h->pps->disable_dbf             
                   << 13) |
-                                              
(h->pps->lists_modification_present_flag            << 14) |
-                                              
(h->pps->slice_header_extension_present_flag        << 15) |
-                                              (IS_IRAP(h)                      
                   << 16) |
-                                              (IS_IDR(h)                       
                   << 17) |
-                                              /* IntraPicFlag */
-                                              (IS_IRAP(h)                      
                   << 18) |
-                                              (0                               
                   << 19);
-    pp->pps_cb_qp_offset            = h->pps->cb_qp_offset;
-    pp->pps_cr_qp_offset            = h->pps->cr_qp_offset;
-    if (h->pps->tiles_enabled_flag) {
-        pp->num_tile_columns_minus1 = h->pps->num_tile_columns - 1;
-        pp->num_tile_rows_minus1    = h->pps->num_tile_rows - 1;
-
-        if (!h->pps->uniform_spacing_flag) {
-            for (i = 0; i < h->pps->num_tile_columns; i++)
-                pp->column_width_minus1[i] = h->pps->column_width[i] - 1;
-
-            for (i = 0; i < h->pps->num_tile_rows; i++)
-                pp->row_height_minus1[i] = h->pps->row_height[i] - 1;
-        }
-    }
-
-    pp->diff_cu_qp_delta_depth           = h->pps->diff_cu_qp_delta_depth;
-    pp->pps_beta_offset_div2             = h->pps->beta_offset / 2;
-    pp->pps_tc_offset_div2               = h->pps->tc_offset / 2;
-    pp->log2_parallel_merge_level_minus2 = h->pps->log2_parallel_merge_level - 
2;
-    pp->CurrPicOrderCntVal               = h->poc;
-
-    // empty the lists
-    memset(&pp->RefPicList, 0xff, sizeof(pp->RefPicList));
-    memset(&pp->RefPicSetStCurrBefore, 0xff, 
sizeof(pp->RefPicSetStCurrBefore));
-    memset(&pp->RefPicSetStCurrAfter, 0xff, sizeof(pp->RefPicSetStCurrAfter));
-    memset(&pp->RefPicSetLtCurr, 0xff, sizeof(pp->RefPicSetLtCurr));
-
-    // fill RefPicList from the DPB
-    for (i = 0, j = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) {
-        const HEVCFrame *frame = &h->DPB[i];
-        if (frame != current_picture && (frame->flags & 
(HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) {
-            fill_picture_entry(&pp->RefPicList[j], 
ff_dxva2_get_surface_index(ctx, frame->frame), !!(frame->flags & 
HEVC_FRAME_FLAG_LONG_REF));
-            pp->PicOrderCntValList[j] = frame->poc;
-            j++;
-        }
-    }
-
-    #define DO_REF_LIST(ref_idx, ref_list) { \
-        const RefPicList *rpl = &h->rps[ref_idx]; \
-        av_assert0(rpl->nb_refs <= FF_ARRAY_ELEMS(pp->ref_list)); \
-        for (j = 0, k = 0; j < rpl->nb_refs; j++) { \
-            if (rpl->ref[j]) { \
-                pp->ref_list[k] = get_refpic_index(pp, 
ff_dxva2_get_surface_index(ctx, rpl->ref[j]->frame)); \
-                k++; \
-            } \
-        } \
-    }
-
-    // Fill short term and long term lists
-    DO_REF_LIST(ST_CURR_BEF, RefPicSetStCurrBefore);
-    DO_REF_LIST(ST_CURR_AFT, RefPicSetStCurrAfter);
-    DO_REF_LIST(LT_CURR, RefPicSetLtCurr);
-
-    pp->StatusReportFeedbackNumber = 1 + ctx->report_id++;
-}
-
-static void fill_scaling_lists(struct dxva_context *ctx, const HEVCContext *h, 
DXVA_Qmatrix_HEVC *qm)
-{
-    unsigned i, j, pos;
-    const ScalingList *sl = h->pps->scaling_list_data_present_flag ?
-                            &h->pps->scaling_list : &h->sps->scaling_list;
-
-    memset(qm, 0, sizeof(*qm));
-    for (i = 0; i < 6; i++) {
-        for (j = 0; j < 16; j++) {
-            pos = 4 * ff_hevc_diag_scan4x4_y[j] + ff_hevc_diag_scan4x4_x[j];
-            qm->ucScalingLists0[i][j] = sl->sl[0][i][pos];
-        }
-
-        for (j = 0; j < 64; j++) {
-            pos = 8 * ff_hevc_diag_scan8x8_y[j] + ff_hevc_diag_scan8x8_x[j];
-            qm->ucScalingLists1[i][j] = sl->sl[1][i][pos];
-            qm->ucScalingLists2[i][j] = sl->sl[2][i][pos];
-
-            if (i < 2)
-                qm->ucScalingLists3[i][j] = sl->sl[3][i][pos];
-        }
-
-        qm->ucScalingListDCCoefSizeID2[i] = sl->sl_dc[0][i];
-        if (i < 2)
-            qm->ucScalingListDCCoefSizeID3[i] = sl->sl_dc[1][i];
-    }
-}
-
-static void fill_slice_short(DXVA_Slice_HEVC_Short *slice,
-                             unsigned position, unsigned size)
-{
-    memset(slice, 0, sizeof(*slice));
-    slice->BSNALunitDataLocation = position;
-    slice->SliceBytesInBuffer    = size;
-    slice->wBadSliceChopping     = 0;
-}
-
-static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
-                                             DXVA2_DecodeBufferDesc *bs,
-                                             DXVA2_DecodeBufferDesc *sc)
-{
-    const HEVCContext *h = avctx->priv_data;
-    struct dxva_context *ctx = avctx->hwaccel_context;
-    const HEVCFrame *current_picture = h->ref;
-    struct hevc_dxva2_picture_context *ctx_pic = 
current_picture->hwaccel_picture_private;
-    DXVA_Slice_HEVC_Short *slice = NULL;
-    void     *dxva_data_ptr;
-    uint8_t  *dxva_data, *current, *end;
-    unsigned dxva_size;
-    void     *slice_data;
-    unsigned slice_size;
-    unsigned padding;
-    unsigned i;
-
-    /* Create an annex B bitstream buffer with only slice NAL and finalize 
slice */
-    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
-                                              DXVA2_BitStreamDateBufferType,
-                                              &dxva_data_ptr, &dxva_size)))
-        return -1;
-
-    dxva_data = dxva_data_ptr;
-    current = dxva_data;
-    end = dxva_data + dxva_size;
-
-    for (i = 0; i < ctx_pic->slice_count; i++) {
-        static const uint8_t start_code[] = { 0, 0, 1 };
-        static const unsigned start_code_size = sizeof(start_code);
-        unsigned position, size;
-
-        slice = &ctx_pic->slice_short[i];
-
-        position = slice->BSNALunitDataLocation;
-        size     = slice->SliceBytesInBuffer;
-        if (start_code_size + size > end - current) {
-            av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream");
-            break;
-        }
-
-        slice->BSNALunitDataLocation = current - dxva_data;
-        slice->SliceBytesInBuffer    = start_code_size + size;
-
-        memcpy(current, start_code, start_code_size);
-        current += start_code_size;
-
-        memcpy(current, &ctx_pic->bitstream[position], size);
-        current += size;
-    }
-    padding = FFMIN(128 - ((current - dxva_data) & 127), end - current);
-    if (slice && padding > 0) {
-        memset(current, 0, padding);
-        current += padding;
-
-        slice->SliceBytesInBuffer += padding;
-    }
-    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
-                                                  
DXVA2_BitStreamDateBufferType)))
-        return -1;
-    if (i < ctx_pic->slice_count)
-        return -1;
-
-    memset(bs, 0, sizeof(*bs));
-    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
-    bs->DataSize             = current - dxva_data;
-    bs->NumMBsInBuffer       = 0;
-
-    slice_data = ctx_pic->slice_short;
-    slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short);
-
-    av_assert0((bs->DataSize & 127) == 0);
-    return ff_dxva2_commit_buffer(avctx, ctx, sc,
-                                  DXVA2_SliceControlBufferType,
-                                  slice_data, slice_size, 0);
-}
-
-
-static int dxva2_hevc_start_frame(AVCodecContext *avctx,
-                                  av_unused const uint8_t *buffer,
-                                  av_unused uint32_t size)
-{
-    const HEVCContext *h = avctx->priv_data;
-    struct dxva_context *ctx = avctx->hwaccel_context;
-    struct hevc_dxva2_picture_context *ctx_pic = 
h->ref->hwaccel_picture_private;
-
-    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
-        return -1;
-    av_assert0(ctx_pic);
-
-    /* Fill up DXVA_PicParams_HEVC */
-    fill_picture_parameters(ctx, h, &ctx_pic->pp);
-
-    /* Fill up DXVA_Qmatrix_HEVC */
-    fill_scaling_lists(ctx, h, &ctx_pic->qm);
-
-    ctx_pic->slice_count    = 0;
-    ctx_pic->bitstream_size = 0;
-    ctx_pic->bitstream      = NULL;
-    return 0;
-}
-
-static int dxva2_hevc_decode_slice(AVCodecContext *avctx,
-                                   const uint8_t *buffer,
-                                   uint32_t size)
-{
-    const HEVCContext *h = avctx->priv_data;
-    const HEVCFrame *current_picture = h->ref;
-    struct hevc_dxva2_picture_context *ctx_pic = 
current_picture->hwaccel_picture_private;
-    unsigned position;
-
-    if (ctx_pic->slice_count >= MAX_SLICES)
-        return -1;
-
-    if (!ctx_pic->bitstream)
-        ctx_pic->bitstream = buffer;
-    ctx_pic->bitstream_size += size;
-
-    position = buffer - ctx_pic->bitstream;
-    fill_slice_short(&ctx_pic->slice_short[ctx_pic->slice_count], position, 
size);
-    ctx_pic->slice_count++;
-
-    return 0;
-}
-
-static int dxva2_hevc_end_frame(AVCodecContext *avctx)
-{
-    HEVCContext *h = avctx->priv_data;
-    struct hevc_dxva2_picture_context *ctx_pic = 
h->ref->hwaccel_picture_private;
-    int scale = ctx_pic->pp.dwCodingParamToolFlags & 1;
-    int ret;
-
-    if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
-        return -1;
-
-    ret = ff_dxva2_common_end_frame(avctx, h->ref->frame,
-                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
-                                    scale ? &ctx_pic->qm : NULL, scale ? 
sizeof(ctx_pic->qm) : 0,
-                                    commit_bitstream_and_slice_buffer);
-    return ret;
-}
-
-AVHWAccel ff_hevc_dxva2_hwaccel = {
-    .name           = "hevc_dxva2",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_HEVC,
-    .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
-    .start_frame    = dxva2_hevc_start_frame,
-    .decode_slice   = dxva2_hevc_decode_slice,
-    .end_frame      = dxva2_hevc_end_frame,
-    .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
-};
diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h
deleted file mode 100644
index b775e6c..0000000
--- a/libavcodec/dxva2_internal.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * DXVA2 HW acceleration
- *
- * copyright (c) 2010 Laurent Aimar
- *
- * This file is part of Libav.
- *
- * Libav 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.
- *
- * Libav 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 Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVCODEC_DXVA_INTERNAL_H
-#define AVCODEC_DXVA_INTERNAL_H
-
-#define COBJMACROS
-
-#include "config.h"
-
-#include "dxva2.h"
-#if HAVE_DXVA_H
-#include <dxva.h>
-#endif
-
-#include "avcodec.h"
-#include "mpegvideo.h"
-
-void *ff_dxva2_get_surface(const AVFrame *frame);
-
-unsigned ff_dxva2_get_surface_index(const struct dxva_context *,
-                                    const AVFrame *frame);
-
-int ff_dxva2_commit_buffer(AVCodecContext *, struct dxva_context *,
-                           DXVA2_DecodeBufferDesc *,
-                           unsigned type, const void *data, unsigned size,
-                           unsigned mb_count);
-
-
-int ff_dxva2_common_end_frame(AVCodecContext *, AVFrame *,
-                              const void *pp, unsigned pp_size,
-                              const void *qm, unsigned qm_size,
-                              int (*commit_bs_si)(AVCodecContext *,
-                                                  DXVA2_DecodeBufferDesc *bs,
-                                                  DXVA2_DecodeBufferDesc 
*slice));
-
-#endif /* AVCODEC_DXVA_INTERNAL_H */
diff --git a/libavcodec/dxva2_mpeg2.c b/libavcodec/dxva2_mpeg2.c
deleted file mode 100644
index 65624e3..0000000
--- a/libavcodec/dxva2_mpeg2.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * MPEG-2 HW acceleration.
- *
- * copyright (c) 2010 Laurent Aimar
- *
- * This file is part of Libav.
- *
- * Libav 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.
- *
- * Libav 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 Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "libavutil/log.h"
-#include "dxva2_internal.h"
-#include "mpegutils.h"
-
-#define MAX_SLICES 1024
-struct dxva2_picture_context {
-    DXVA_PictureParameters pp;
-    DXVA_QmatrixData       qm;
-    unsigned               slice_count;
-    DXVA_SliceInfo         slice[MAX_SLICES];
-
-    const uint8_t          *bitstream;
-    unsigned               bitstream_size;
-};
-
-static void fill_picture_parameters(AVCodecContext *avctx,
-                                    struct dxva_context *ctx,
-                                    const struct MpegEncContext *s,
-                                    DXVA_PictureParameters *pp)
-{
-    const Picture *current_picture = s->current_picture_ptr;
-    int is_field = s->picture_structure != PICT_FRAME;
-
-    memset(pp, 0, sizeof(*pp));
-    pp->wDecodedPictureIndex         = ff_dxva2_get_surface_index(ctx, 
current_picture->f);
-    pp->wDeblockedPictureIndex       = 0;
-    if (s->pict_type != AV_PICTURE_TYPE_I)
-        pp->wForwardRefPictureIndex  = ff_dxva2_get_surface_index(ctx, 
s->last_picture.f);
-    else
-        pp->wForwardRefPictureIndex  = 0xffff;
-    if (s->pict_type == AV_PICTURE_TYPE_B)
-        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, 
s->next_picture.f);
-    else
-        pp->wBackwardRefPictureIndex = 0xffff;
-    pp->wPicWidthInMBminus1          = s->mb_width  - 1;
-    pp->wPicHeightInMBminus1         = (s->mb_height >> is_field) - 1;
-    pp->bMacroblockWidthMinus1       = 15;
-    pp->bMacroblockHeightMinus1      = 15;
-    pp->bBlockWidthMinus1            = 7;
-    pp->bBlockHeightMinus1           = 7;
-    pp->bBPPminus1                   = 7;
-    pp->bPicStructure                = s->picture_structure;
-    pp->bSecondField                 = is_field && !s->first_field;
-    pp->bPicIntra                    = s->pict_type == AV_PICTURE_TYPE_I;
-    pp->bPicBackwardPrediction       = s->pict_type == AV_PICTURE_TYPE_B;
-    pp->bBidirectionalAveragingMode  = 0;
-    pp->bMVprecisionAndChromaRelation= 0; /* FIXME */
-    pp->bChromaFormat                = s->chroma_format;
-    pp->bPicScanFixed                = 1;
-    pp->bPicScanMethod               = s->alternate_scan ? 1 : 0;
-    pp->bPicReadbackRequests         = 0;
-    pp->bRcontrol                    = 0;
-    pp->bPicSpatialResid8            = 0;
-    pp->bPicOverflowBlocks           = 0;
-    pp->bPicExtrapolation            = 0;
-    pp->bPicDeblocked                = 0;
-    pp->bPicDeblockConfined          = 0;
-    pp->bPic4MVallowed               = 0;
-    pp->bPicOBMC                     = 0;
-    pp->bPicBinPB                    = 0;
-    pp->bMV_RPS                      = 0;
-    pp->bReservedBits                = 0;
-    pp->wBitstreamFcodes             = (s->mpeg_f_code[0][0] << 12) |
-                                       (s->mpeg_f_code[0][1] <<  8) |
-                                       (s->mpeg_f_code[1][0] <<  4) |
-                                       (s->mpeg_f_code[1][1]      );
-    pp->wBitstreamPCEelements        = (s->intra_dc_precision         << 14) |
-                                       (s->picture_structure          << 12) |
-                                       (s->top_field_first            << 11) |
-                                       (s->frame_pred_frame_dct       << 10) |
-                                       (s->concealment_motion_vectors <<  9) |
-                                       (s->q_scale_type               <<  8) |
-                                       (s->intra_vlc_format           <<  7) |
-                                       (s->alternate_scan             <<  6) |
-                                       (s->repeat_first_field         <<  5) |
-                                       (s->chroma_420_type            <<  4) |
-                                       (s->progressive_frame          <<  3);
-    pp->bBitstreamConcealmentNeed    = 0;
-    pp->bBitstreamConcealmentMethod  = 0;
-}
-
-static void fill_quantization_matrices(AVCodecContext *avctx,
-                                       struct dxva_context *ctx,
-                                       const struct MpegEncContext *s,
-                                       DXVA_QmatrixData *qm)
-{
-    int i;
-    for (i = 0; i < 4; i++)
-        qm->bNewQmatrix[i] = 1;
-    for (i = 0; i < 64; i++) {
-        int n = s->idsp.idct_permutation[ff_zigzag_direct[i]];
-        qm->Qmatrix[0][i] = s->intra_matrix[n];;
-        qm->Qmatrix[1][i] = s->inter_matrix[n];;
-        qm->Qmatrix[2][i] = s->chroma_intra_matrix[n];;
-        qm->Qmatrix[3][i] = s->chroma_inter_matrix[n];;
-    }
-}
-
-static void fill_slice(AVCodecContext *avctx,
-                       const struct MpegEncContext *s,
-                       DXVA_SliceInfo *slice,
-                       unsigned position,
-                       const uint8_t *buffer, unsigned size)
-{
-    int is_field = s->picture_structure != PICT_FRAME;
-    GetBitContext gb;
-
-    memset(slice, 0, sizeof(*slice));
-    slice->wHorizontalPosition = s->mb_x;
-    slice->wVerticalPosition   = s->mb_y >> is_field;
-    slice->dwSliceBitsInBuffer = 8 * size;
-    slice->dwSliceDataLocation = position;
-    slice->bStartCodeBitOffset = 0;
-    slice->bReservedBits       = 0;
-    /* XXX We store the index of the first MB and it will be fixed later */
-    slice->wNumberMBsInSlice   = (s->mb_y >> is_field) * s->mb_width + s->mb_x;
-    slice->wBadSliceChopping   = 0;
-
-    init_get_bits(&gb, &buffer[4], 8 * (size - 4));
-
-    slice->wQuantizerScaleCode = get_bits(&gb, 5);
-    while (get_bits1(&gb))
-        skip_bits(&gb, 8);
-
-    slice->wMBbitOffset        = 4 * 8 + get_bits_count(&gb);
-}
-static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
-                                             DXVA2_DecodeBufferDesc *bs,
-                                             DXVA2_DecodeBufferDesc *sc)
-{
-    const struct MpegEncContext *s = avctx->priv_data;
-    struct dxva_context *ctx = avctx->hwaccel_context;
-    struct dxva2_picture_context *ctx_pic =
-        s->current_picture_ptr->hwaccel_picture_private;
-    const int is_field = s->picture_structure != PICT_FRAME;
-    const unsigned mb_count = s->mb_width * (s->mb_height >> is_field);
-    void     *dxva_data_ptr;
-    uint8_t  *dxva_data, *current, *end;
-    unsigned dxva_size;
-    unsigned i;
-
-    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
-                                              DXVA2_BitStreamDateBufferType,
-                                              &dxva_data_ptr, &dxva_size)))
-        return -1;
-
-    dxva_data = dxva_data_ptr;
-    current = dxva_data;
-    end = dxva_data + dxva_size;
-
-    for (i = 0; i < ctx_pic->slice_count; i++) {
-        DXVA_SliceInfo *slice = &ctx_pic->slice[i];
-        unsigned position = slice->dwSliceDataLocation;
-        unsigned size     = slice->dwSliceBitsInBuffer / 8;
-        if (size > end - current) {
-            av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream");
-            break;
-        }
-        slice->dwSliceDataLocation = current - dxva_data;
-
-        if (i < ctx_pic->slice_count - 1)
-            slice->wNumberMBsInSlice =
-                slice[1].wNumberMBsInSlice - slice[0].wNumberMBsInSlice;
-        else
-            slice->wNumberMBsInSlice =
-                mb_count - slice[0].wNumberMBsInSlice;
-
-        memcpy(current, &ctx_pic->bitstream[position], size);
-        current += size;
-    }
-    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
-                                                  
DXVA2_BitStreamDateBufferType)))
-        return -1;
-    if (i < ctx_pic->slice_count)
-        return -1;
-
-    memset(bs, 0, sizeof(*bs));
-    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
-    bs->DataSize             = current - dxva_data;
-    bs->NumMBsInBuffer       = mb_count;
-
-    return ff_dxva2_commit_buffer(avctx, ctx, sc,
-                                  DXVA2_SliceControlBufferType,
-                                  ctx_pic->slice,
-                                  ctx_pic->slice_count * 
sizeof(*ctx_pic->slice),
-                                  mb_count);
-}
-
-static int dxva2_mpeg2_start_frame(AVCodecContext *avctx,
-                                   av_unused const uint8_t *buffer,
-                                   av_unused uint32_t size)
-{
-    const struct MpegEncContext *s = avctx->priv_data;
-    struct dxva_context *ctx = avctx->hwaccel_context;
-    struct dxva2_picture_context *ctx_pic =
-        s->current_picture_ptr->hwaccel_picture_private;
-
-    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
-        return -1;
-    assert(ctx_pic);
-
-    fill_picture_parameters(avctx, ctx, s, &ctx_pic->pp);
-    fill_quantization_matrices(avctx, ctx, s, &ctx_pic->qm);
-
-    ctx_pic->slice_count    = 0;
-    ctx_pic->bitstream_size = 0;
-    ctx_pic->bitstream      = NULL;
-    return 0;
-}
-
-static int dxva2_mpeg2_decode_slice(AVCodecContext *avctx,
-                                    const uint8_t *buffer, uint32_t size)
-{
-    const struct MpegEncContext *s = avctx->priv_data;
-    struct dxva2_picture_context *ctx_pic =
-        s->current_picture_ptr->hwaccel_picture_private;
-    unsigned position;
-
-    if (ctx_pic->slice_count >= MAX_SLICES) {
-        avpriv_request_sample(avctx, "%d slices in dxva2",
-                              ctx_pic->slice_count);
-        return -1;
-    }
-    if (!ctx_pic->bitstream)
-        ctx_pic->bitstream = buffer;
-    ctx_pic->bitstream_size += size;
-
-    position = buffer - ctx_pic->bitstream;
-    fill_slice(avctx, s, &ctx_pic->slice[ctx_pic->slice_count++], position,
-               buffer, size);
-    return 0;
-}
-
-static int dxva2_mpeg2_end_frame(AVCodecContext *avctx)
-{
-    struct MpegEncContext *s = avctx->priv_data;
-    struct dxva2_picture_context *ctx_pic =
-        s->current_picture_ptr->hwaccel_picture_private;
-    int ret;
-
-    if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
-        return -1;
-    ret = ff_dxva2_common_end_frame(avctx, s->current_picture_ptr->f,
-                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
-                                    &ctx_pic->qm, sizeof(ctx_pic->qm),
-                                    commit_bitstream_and_slice_buffer);
-    if (!ret)
-        ff_mpeg_draw_horiz_band(s, 0, avctx->height);
-    return ret;
-}
-
-AVHWAccel ff_mpeg2_dxva2_hwaccel = {
-    .name           = "mpeg2_dxva2",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_MPEG2VIDEO,
-    .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
-    .start_frame    = dxva2_mpeg2_start_frame,
-    .decode_slice   = dxva2_mpeg2_decode_slice,
-    .end_frame      = dxva2_mpeg2_end_frame,
-    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
-};
diff --git a/libavcodec/dxva2_vc1.c b/libavcodec/dxva2_vc1.c
deleted file mode 100644
index 1524b51..0000000
--- a/libavcodec/dxva2_vc1.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * DXVA2 WMV3/VC-1 HW acceleration.
- *
- * copyright (c) 2010 Laurent Aimar
- *
- * This file is part of Libav.
- *
- * Libav 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.
- *
- * Libav 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 Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "dxva2_internal.h"
-#include "mpegutils.h"
-#include "vc1.h"
-#include "vc1data.h"
-
-struct dxva2_picture_context {
-    DXVA_PictureParameters pp;
-    DXVA_SliceInfo         si;
-
-    const uint8_t          *bitstream;
-    unsigned               bitstream_size;
-};
-
-static void fill_picture_parameters(AVCodecContext *avctx,
-                                    struct dxva_context *ctx, const VC1Context 
*v,
-                                    DXVA_PictureParameters *pp)
-{
-    const MpegEncContext *s = &v->s;
-    const Picture *current_picture = s->current_picture_ptr;
-
-    memset(pp, 0, sizeof(*pp));
-    pp->wDecodedPictureIndex    =
-    pp->wDeblockedPictureIndex  = ff_dxva2_get_surface_index(ctx, 
current_picture->f);
-    if (s->pict_type != AV_PICTURE_TYPE_I && !v->bi_type)
-        pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, 
s->last_picture.f);
-    else
-        pp->wForwardRefPictureIndex = 0xffff;
-    if (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type)
-        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, 
s->next_picture.f);
-    else
-        pp->wBackwardRefPictureIndex = 0xffff;
-    if (v->profile == PROFILE_ADVANCED) {
-        /* It is the cropped width/height -1 of the frame */
-        pp->wPicWidthInMBminus1 = avctx->width  - 1;
-        pp->wPicHeightInMBminus1= avctx->height - 1;
-    } else {
-        /* It is the coded width/height in macroblock -1 of the frame */
-        pp->wPicWidthInMBminus1 = s->mb_width  - 1;
-        pp->wPicHeightInMBminus1= s->mb_height - 1;
-    }
-    pp->bMacroblockWidthMinus1  = 15;
-    pp->bMacroblockHeightMinus1 = 15;
-    pp->bBlockWidthMinus1       = 7;
-    pp->bBlockHeightMinus1      = 7;
-    pp->bBPPminus1              = 7;
-    if (s->picture_structure & PICT_TOP_FIELD)
-        pp->bPicStructure      |= 0x01;
-    if (s->picture_structure & PICT_BOTTOM_FIELD)
-        pp->bPicStructure      |= 0x02;
-    pp->bSecondField            = v->interlace && v->fcm != ILACE_FIELD && 
!s->first_field;
-    pp->bPicIntra               = s->pict_type == AV_PICTURE_TYPE_I || 
v->bi_type;
-    pp->bPicBackwardPrediction  = s->pict_type == AV_PICTURE_TYPE_B && 
!v->bi_type;
-    pp->bBidirectionalAveragingMode = (1                                       
    << 7) |
-                                      ((ctx->cfg->ConfigIntraResidUnsigned != 
0)   << 6) |
-                                      ((ctx->cfg->ConfigResidDiffAccelerator 
!= 0) << 5) |
-                                      ((v->lumscale != 32 || v->lumshift != 0) 
    << 4) |
-                                      ((v->profile == PROFILE_ADVANCED)        
    << 3);
-    pp->bMVprecisionAndChromaRelation = ((v->mv_mode == 
MV_PMODE_1MV_HPEL_BILIN) << 3) |
-                                        (1                                     
  << 2) |
-                                        (0                                     
  << 1) |
-                                        (!s->quarter_sample                    
      );
-    pp->bChromaFormat           = v->chromaformat;
-    ctx->report_id++;
-    if (ctx->report_id >= (1 << 16))
-        ctx->report_id = 1;
-    pp->bPicScanFixed           = ctx->report_id >> 8;
-    pp->bPicScanMethod          = ctx->report_id & 0xff;
-    pp->bPicReadbackRequests    = 0;
-    pp->bRcontrol               = v->rnd;
-    pp->bPicSpatialResid8       = (v->panscanflag  << 7) |
-                                  (v->refdist_flag << 6) |
-                                  (s->loop_filter  << 5) |
-                                  (v->fastuvmc     << 4) |
-                                  (v->extended_mv  << 3) |
-                                  (v->dquant       << 1) |
-                                  (v->vstransform      );
-    pp->bPicOverflowBlocks      = (v->quantizer_mode << 6) |
-                                  (v->multires       << 5) |
-                                  (v->resync_marker  << 4) |
-                                  (v->rangered       << 3) |
-                                  (s->max_b_frames       );
-    pp->bPicExtrapolation       = (!v->interlace || v->fcm == PROGRESSIVE) ? 1 
: 2;
-    pp->bPicDeblocked           = ((!pp->bPicBackwardPrediction && v->overlap) 
       << 6) |
-                                  ((v->profile != PROFILE_ADVANCED && 
v->rangeredfrm) << 5) |
-                                  (s->loop_filter                              
       << 1);
-    pp->bPicDeblockConfined     = (v->postprocflag             << 7) |
-                                  (v->broadcast                << 6) |
-                                  (v->interlace                << 5) |
-                                  (v->tfcntrflag               << 4) |
-                                  (v->finterpflag              << 3) |
-                                  ((s->pict_type != AV_PICTURE_TYPE_B) << 2) |
-                                  (v->psf                      << 1) |
-                                  (v->extended_dmv                 );
-    if (s->pict_type != AV_PICTURE_TYPE_I)
-        pp->bPic4MVallowed      = v->mv_mode == MV_PMODE_MIXED_MV ||
-                                  (v->mv_mode == MV_PMODE_INTENSITY_COMP &&
-                                   v->mv_mode2 == MV_PMODE_MIXED_MV);
-    if (v->profile == PROFILE_ADVANCED)
-        pp->bPicOBMC            = (v->range_mapy_flag  << 7) |
-                                  (v->range_mapy       << 4) |
-                                  (v->range_mapuv_flag << 3) |
-                                  (v->range_mapuv          );
-    pp->bPicBinPB               = 0;
-    pp->bMV_RPS                 = 0;
-    pp->bReservedBits           = 0;
-    if (s->picture_structure == PICT_FRAME) {
-        pp->wBitstreamFcodes        = v->lumscale;
-        pp->wBitstreamPCEelements   = v->lumshift;
-    } else {
-        /* Syntax: (top_field_param << 8) | bottom_field_param */
-        pp->wBitstreamFcodes        = (v->lumscale << 8) | v->lumscale;
-        pp->wBitstreamPCEelements   = (v->lumshift << 8) | v->lumshift;
-    }
-    pp->bBitstreamConcealmentNeed   = 0;
-    pp->bBitstreamConcealmentMethod = 0;
-}
-
-static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice,
-                       unsigned position, unsigned size)
-{
-    const VC1Context *v = avctx->priv_data;
-    const MpegEncContext *s = &v->s;
-
-    memset(slice, 0, sizeof(*slice));
-    slice->wHorizontalPosition = 0;
-    slice->wVerticalPosition   = s->mb_y;
-    slice->dwSliceBitsInBuffer = 8 * size;
-    slice->dwSliceDataLocation = position;
-    slice->bStartCodeBitOffset = 0;
-    slice->bReservedBits       = 0;
-    slice->wMBbitOffset        = get_bits_count(&s->gb);
-    slice->wNumberMBsInSlice   = s->mb_width * s->mb_height; /* XXX We assume 
1 slice */
-    slice->wQuantizerScaleCode = v->pq;
-    slice->wBadSliceChopping   = 0;
-}
-
-static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
-                                             DXVA2_DecodeBufferDesc *bs,
-                                             DXVA2_DecodeBufferDesc *sc)
-{
-    const VC1Context *v = avctx->priv_data;
-    struct dxva_context *ctx = avctx->hwaccel_context;
-    const MpegEncContext *s = &v->s;
-    struct dxva2_picture_context *ctx_pic = 
s->current_picture_ptr->hwaccel_picture_private;
-
-    DXVA_SliceInfo *slice = &ctx_pic->si;
-
-    static const uint8_t start_code[] = { 0, 0, 1, 0x0d };
-    const unsigned start_code_size = avctx->codec_id == AV_CODEC_ID_VC1 ? 
sizeof(start_code) : 0;
-    const unsigned slice_size = slice->dwSliceBitsInBuffer / 8;
-    const unsigned padding = 128 - ((start_code_size + slice_size) & 127);
-    const unsigned data_size = start_code_size + slice_size + padding;
-
-    void     *dxva_data_ptr;
-    uint8_t  *dxva_data;
-    unsigned dxva_size;
-    int result;
-
-    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
-                                              DXVA2_BitStreamDateBufferType,
-                                              &dxva_data_ptr, &dxva_size)))
-        return -1;
-
-    dxva_data = dxva_data_ptr;
-    result = data_size <= dxva_size ? 0 : -1;
-    if (!result) {
-        if (start_code_size > 0)
-            memcpy(dxva_data, start_code, start_code_size);
-        memcpy(dxva_data + start_code_size,
-               ctx_pic->bitstream + slice->dwSliceDataLocation, slice_size);
-        if (padding > 0)
-            memset(dxva_data + start_code_size + slice_size, 0, padding);
-        slice->dwSliceBitsInBuffer = 8 * data_size;
-    }
-    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
-                                                  
DXVA2_BitStreamDateBufferType)))
-        return -1;
-    if (result)
-        return result;
-
-    memset(bs, 0, sizeof(*bs));
-    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
-    bs->DataSize             = data_size;
-    bs->NumMBsInBuffer       = s->mb_width * s->mb_height;
-    assert((bs->DataSize & 127) == 0);
-
-    return ff_dxva2_commit_buffer(avctx, ctx, sc,
-                                  DXVA2_SliceControlBufferType,
-                                  slice, sizeof(*slice), bs->NumMBsInBuffer);
-}
-
-static int dxva2_vc1_start_frame(AVCodecContext *avctx,
-                                 av_unused const uint8_t *buffer,
-                                 av_unused uint32_t size)
-{
-    const VC1Context *v = avctx->priv_data;
-    struct dxva_context *ctx = avctx->hwaccel_context;
-    struct dxva2_picture_context *ctx_pic = 
v->s.current_picture_ptr->hwaccel_picture_private;
-
-    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
-        return -1;
-    assert(ctx_pic);
-
-    fill_picture_parameters(avctx, ctx, v, &ctx_pic->pp);
-
-    ctx_pic->bitstream_size = 0;
-    ctx_pic->bitstream      = NULL;
-    return 0;
-}
-
-static int dxva2_vc1_decode_slice(AVCodecContext *avctx,
-                                  const uint8_t *buffer,
-                                  uint32_t size)
-{
-    const VC1Context *v = avctx->priv_data;
-    const Picture *current_picture = v->s.current_picture_ptr;
-    struct dxva2_picture_context *ctx_pic = 
current_picture->hwaccel_picture_private;
-
-    if (ctx_pic->bitstream_size > 0)
-        return -1;
-
-    if (avctx->codec_id == AV_CODEC_ID_VC1 &&
-        size >= 4 && IS_MARKER(AV_RB32(buffer))) {
-        buffer += 4;
-        size   -= 4;
-    }
-
-    ctx_pic->bitstream_size = size;
-    ctx_pic->bitstream      = buffer;
-
-    fill_slice(avctx, &ctx_pic->si, 0, size);
-    return 0;
-}
-
-static int dxva2_vc1_end_frame(AVCodecContext *avctx)
-{
-    VC1Context *v = avctx->priv_data;
-    struct dxva2_picture_context *ctx_pic = 
v->s.current_picture_ptr->hwaccel_picture_private;
-    int ret;
-
-    if (ctx_pic->bitstream_size <= 0)
-        return -1;
-
-    ret = ff_dxva2_common_end_frame(avctx, v->s.current_picture_ptr->f,
-                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
-                                    NULL, 0,
-                                    commit_bitstream_and_slice_buffer);
-    if (!ret)
-        ff_mpeg_draw_horiz_band(&v->s, 0, avctx->height);
-    return ret;
-}
-
-#if CONFIG_WMV3_DXVA2_HWACCEL
-AVHWAccel ff_wmv3_dxva2_hwaccel = {
-    .name           = "wmv3_dxva2",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_WMV3,
-    .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
-    .start_frame    = dxva2_vc1_start_frame,
-    .decode_slice   = dxva2_vc1_decode_slice,
-    .end_frame      = dxva2_vc1_end_frame,
-    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
-};
-#endif
-
-AVHWAccel ff_vc1_dxva2_hwaccel = {
-    .name           = "vc1_dxva2",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_VC1,
-    .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
-    .start_frame    = dxva2_vc1_start_frame,
-    .decode_slice   = dxva2_vc1_decode_slice,
-    .end_frame      = dxva2_vc1_end_frame,
-    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
-};
diff --git a/libavcodec/dxva_h264_template.c b/libavcodec/dxva_h264_template.c
new file mode 100644
index 0000000..78c0f71
--- /dev/null
+++ b/libavcodec/dxva_h264_template.c
@@ -0,0 +1,475 @@
+/*
+ * DXVA2 H264 HW acceleration.
+ *
+ * copyright (c) 2009 Laurent Aimar
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "dxva_internal_template.h"
+#include "h264.h"
+#include "h264data.h"
+#include "mpegutils.h"
+
+struct dxva2_picture_context {
+    DXVA_PicParams_H264   pp;
+    DXVA_Qmatrix_H264     qm;
+    unsigned              slice_count;
+    DXVA_Slice_H264_Short slice_short[MAX_SLICES];
+    DXVA_Slice_H264_Long  slice_long[MAX_SLICES];
+    const uint8_t         *bitstream;
+    unsigned              bitstream_size;
+};
+
+static void fill_picture_entry(DXVA_PicEntry_H264 *pic,
+                               unsigned index, unsigned flag)
+{
+    assert((index&0x7f) == index && (flag&0x01) == flag);
+    pic->bPicEntry = index | (flag << 7);
+}
+
+static void fill_picture_parameters(struct dxva_context *ctx, const 
H264Context *h,
+                                    DXVA_PicParams_H264 *pp)
+{
+    const H264Picture *current_picture = h->cur_pic_ptr;
+    int i, j;
+
+    memset(pp, 0, sizeof(*pp));
+    /* Configure current picture */
+    fill_picture_entry(&pp->CurrPic,
+                       ff_dxva2_get_surface_index(ctx, current_picture->f),
+                       h->picture_structure == PICT_BOTTOM_FIELD);
+    /* Configure the set of references */
+    pp->UsedForReferenceFlags  = 0;
+    pp->NonExistingFrameFlags  = 0;
+    for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->RefFrameList); i++) {
+        const H264Picture *r;
+        if (j < h->short_ref_count) {
+            r = h->short_ref[j++];
+        } else {
+            r = NULL;
+            while (!r && j < h->short_ref_count + 16)
+                r = h->long_ref[j++ - h->short_ref_count];
+        }
+        if (r) {
+            fill_picture_entry(&pp->RefFrameList[i],
+                               ff_dxva2_get_surface_index(ctx, r->f),
+                               r->long_ref != 0);
+
+            if ((r->reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX)
+                pp->FieldOrderCntList[i][0] = r->field_poc[0];
+            if ((r->reference & PICT_BOTTOM_FIELD) && r->field_poc[1] != 
INT_MAX)
+                pp->FieldOrderCntList[i][1] = r->field_poc[1];
+
+            pp->FrameNumList[i] = r->long_ref ? r->pic_id : r->frame_num;
+            if (r->reference & PICT_TOP_FIELD)
+                pp->UsedForReferenceFlags |= 1 << (2*i + 0);
+            if (r->reference & PICT_BOTTOM_FIELD)
+                pp->UsedForReferenceFlags |= 1 << (2*i + 1);
+        } else {
+            pp->RefFrameList[i].bPicEntry = 0xff;
+            pp->FieldOrderCntList[i][0]   = 0;
+            pp->FieldOrderCntList[i][1]   = 0;
+            pp->FrameNumList[i]           = 0;
+        }
+    }
+
+    pp->wFrameWidthInMbsMinus1        = h->mb_width  - 1;
+    pp->wFrameHeightInMbsMinus1       = h->mb_height - 1;
+    pp->num_ref_frames                = h->sps.ref_frame_count;
+
+    pp->wBitFields                    = ((h->picture_structure != PICT_FRAME) 
<<  0) |
+                                        ((h->sps.mb_aff &&
+                                        (h->picture_structure == PICT_FRAME)) 
<<  1) |
+                                        (h->sps.residual_color_transform_flag 
<<  2) |
+                                        /* sp_for_switch_flag (not implemented 
by Libav) */
+                                        (0                                    
<<  3) |
+                                        (h->sps.chroma_format_idc             
<<  4) |
+                                        ((h->nal_ref_idc != 0)                
<<  6) |
+                                        (h->pps.constrained_intra_pred        
<<  7) |
+                                        (h->pps.weighted_pred                 
<<  8) |
+                                        (h->pps.weighted_bipred_idc           
<<  9) |
+                                        /* MbsConsecutiveFlag */
+                                        (1                                    
<< 11) |
+                                        (h->sps.frame_mbs_only_flag           
<< 12) |
+                                        (h->pps.transform_8x8_mode            
<< 13) |
+                                        ((h->sps.level_idc >= 31)             
<< 14) |
+                                        /* IntraPicFlag (Modified if we detect 
a non
+                                         * intra slice in 
dxva2_h264_decode_slice) */
+                                        (1                                    
<< 15);
+
+    pp->bit_depth_luma_minus8         = h->sps.bit_depth_luma - 8;
+    pp->bit_depth_chroma_minus8       = h->sps.bit_depth_chroma - 8;
+    if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG)
+        pp->Reserved16Bits            = 0;
+    else if (ctx->workaround & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO)
+        pp->Reserved16Bits            = 0x34c;
+    else
+        pp->Reserved16Bits            = 3; /* FIXME is there a way to detect 
the right mode ? */
+    pp->StatusReportFeedbackNumber    = 1 + ctx->report_id++;
+    pp->CurrFieldOrderCnt[0] = 0;
+    if ((h->picture_structure & PICT_TOP_FIELD) &&
+        current_picture->field_poc[0] != INT_MAX)
+        pp->CurrFieldOrderCnt[0] = current_picture->field_poc[0];
+    pp->CurrFieldOrderCnt[1] = 0;
+    if ((h->picture_structure & PICT_BOTTOM_FIELD) &&
+        current_picture->field_poc[1] != INT_MAX)
+        pp->CurrFieldOrderCnt[1] = current_picture->field_poc[1];
+    pp->pic_init_qs_minus26           = h->pps.init_qs - 26;
+    pp->chroma_qp_index_offset        = h->pps.chroma_qp_index_offset[0];
+    pp->second_chroma_qp_index_offset = h->pps.chroma_qp_index_offset[1];
+    pp->ContinuationFlag              = 1;
+    pp->pic_init_qp_minus26           = h->pps.init_qp - 26;
+    pp->num_ref_idx_l0_active_minus1  = h->pps.ref_count[0] - 1;
+    pp->num_ref_idx_l1_active_minus1  = h->pps.ref_count[1] - 1;
+    pp->Reserved8BitsA                = 0;
+    pp->frame_num                     = h->frame_num;
+    pp->log2_max_frame_num_minus4     = h->sps.log2_max_frame_num - 4;
+    pp->pic_order_cnt_type            = h->sps.poc_type;
+    if (h->sps.poc_type == 0)
+        pp->log2_max_pic_order_cnt_lsb_minus4 = h->sps.log2_max_poc_lsb - 4;
+    else if (h->sps.poc_type == 1)
+        pp->delta_pic_order_always_zero_flag = 
h->sps.delta_pic_order_always_zero_flag;
+    pp->direct_8x8_inference_flag     = h->sps.direct_8x8_inference_flag;
+    pp->entropy_coding_mode_flag      = h->pps.cabac;
+    pp->pic_order_present_flag        = h->pps.pic_order_present;
+    pp->num_slice_groups_minus1       = h->pps.slice_group_count - 1;
+    pp->slice_group_map_type          = h->pps.mb_slice_group_map_type;
+    pp->deblocking_filter_control_present_flag = 
h->pps.deblocking_filter_parameters_present;
+    pp->redundant_pic_cnt_present_flag= h->pps.redundant_pic_cnt_present;
+    pp->Reserved8BitsB                = 0;
+    pp->slice_group_change_rate_minus1= 0;  /* XXX not implemented by Libav */
+    //pp->SliceGroupMap[810];               /* XXX not implemented by Libav */
+}
+
+static void fill_scaling_lists(struct dxva_context *ctx, const H264Context *h, 
DXVA_Qmatrix_H264 *qm)
+{
+    unsigned i, j;
+    memset(qm, 0, sizeof(*qm));
+    if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) {
+        for (i = 0; i < 6; i++)
+            for (j = 0; j < 16; j++)
+                qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][j];
+
+        for (i = 0; i < 64; i++) {
+            qm->bScalingLists8x8[0][i] = h->pps.scaling_matrix8[0][i];
+            qm->bScalingLists8x8[1][i] = h->pps.scaling_matrix8[3][i];
+        }
+    } else {
+        for (i = 0; i < 6; i++)
+            for (j = 0; j < 16; j++)
+                qm->bScalingLists4x4[i][j] = 
h->pps.scaling_matrix4[i][zigzag_scan[j]];
+
+        for (i = 0; i < 64; i++) {
+            qm->bScalingLists8x8[0][i] = 
h->pps.scaling_matrix8[0][ff_zigzag_direct[i]];
+            qm->bScalingLists8x8[1][i] = 
h->pps.scaling_matrix8[3][ff_zigzag_direct[i]];
+        }
+    }
+}
+
+static int is_slice_short(struct dxva_context *ctx)
+{
+    assert(ctx->cfg->ConfigBitstreamRaw == 1 ||
+           ctx->cfg->ConfigBitstreamRaw == 2);
+    return ctx->cfg->ConfigBitstreamRaw == 2;
+}
+
+static void fill_slice_short(DXVA_Slice_H264_Short *slice,
+                             unsigned position, unsigned size)
+{
+    memset(slice, 0, sizeof(*slice));
+    slice->BSNALunitDataLocation = position;
+    slice->SliceBytesInBuffer    = size;
+    slice->wBadSliceChopping     = 0;
+}
+
+static int get_refpic_index(const DXVA_PicParams_H264 *pp, int surface_index)
+{
+    int i;
+    for (i = 0; i < FF_ARRAY_ELEMS(pp->RefFrameList); i++) {
+        if ((pp->RefFrameList[i].bPicEntry & 0x7f) == surface_index)
+          return i;
+    }
+    return 0x7f;
+}
+
+static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
+                            const DXVA_PicParams_H264 *pp, unsigned position, 
unsigned size)
+{
+    const H264Context *h = avctx->priv_data;
+    H264SliceContext *sl = &h->slice_ctx[0];
+    struct dxva_context *ctx = avctx->hwaccel_context;
+    unsigned list;
+
+    memset(slice, 0, sizeof(*slice));
+    slice->BSNALunitDataLocation = position;
+    slice->SliceBytesInBuffer    = size;
+    slice->wBadSliceChopping     = 0;
+
+    slice->first_mb_in_slice     = (sl->mb_y >> FIELD_OR_MBAFF_PICTURE(h)) * 
h->mb_width + sl->mb_x;
+    slice->NumMbsForSlice        = 0; /* XXX it is set once we have all slices 
*/
+    slice->BitOffsetToSliceData  = get_bits_count(&sl->gb);
+    slice->slice_type            = ff_h264_get_slice_type(sl);
+    if (sl->slice_type_fixed)
+        slice->slice_type += 5;
+    slice->luma_log2_weight_denom       = sl->luma_log2_weight_denom;
+    slice->chroma_log2_weight_denom     = sl->chroma_log2_weight_denom;
+    if (sl->list_count > 0)
+        slice->num_ref_idx_l0_active_minus1 = sl->ref_count[0] - 1;
+    if (sl->list_count > 1)
+        slice->num_ref_idx_l1_active_minus1 = sl->ref_count[1] - 1;
+    slice->slice_alpha_c0_offset_div2   = sl->slice_alpha_c0_offset / 2;
+    slice->slice_beta_offset_div2       = sl->slice_beta_offset     / 2;
+    slice->Reserved8Bits                = 0;
+
+    for (list = 0; list < 2; list++) {
+        unsigned i;
+        for (i = 0; i < FF_ARRAY_ELEMS(slice->RefPicList[list]); i++) {
+            if (list < sl->list_count && i < sl->ref_count[list]) {
+                const H264Picture *r = sl->ref_list[list][i].parent;
+                unsigned plane;
+                unsigned index;
+                if (ctx->workaround & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO)
+                    index = ff_dxva2_get_surface_index(ctx, r->f);
+                else
+                    index = get_refpic_index(pp, 
ff_dxva2_get_surface_index(ctx, r->f));
+                fill_picture_entry(&slice->RefPicList[list][i], index,
+                                   r->reference == PICT_BOTTOM_FIELD);
+                for (plane = 0; plane < 3; plane++) {
+                    int w, o;
+                    if (plane == 0 && sl->luma_weight_flag[list]) {
+                        w = sl->luma_weight[i][list][0];
+                        o = sl->luma_weight[i][list][1];
+                    } else if (plane >= 1 && sl->chroma_weight_flag[list]) {
+                        w = sl->chroma_weight[i][list][plane-1][0];
+                        o = sl->chroma_weight[i][list][plane-1][1];
+                    } else {
+                        w = 1 << (plane == 0 ? sl->luma_log2_weight_denom :
+                                               sl->chroma_log2_weight_denom);
+                        o = 0;
+                    }
+                    slice->Weights[list][i][plane][0] = w;
+                    slice->Weights[list][i][plane][1] = o;
+                }
+            } else {
+                unsigned plane;
+                slice->RefPicList[list][i].bPicEntry = 0xff;
+                for (plane = 0; plane < 3; plane++) {
+                    slice->Weights[list][i][plane][0] = 0;
+                    slice->Weights[list][i][plane][1] = 0;
+                }
+            }
+        }
+    }
+    slice->slice_qs_delta    = 0; /* XXX not implemented by Libav */
+    slice->slice_qp_delta    = sl->qscale - h->pps.init_qp;
+    slice->redundant_pic_cnt = sl->redundant_pic_count;
+    if (sl->slice_type == AV_PICTURE_TYPE_B)
+        slice->direct_spatial_mv_pred_flag = sl->direct_spatial_mv_pred;
+    slice->cabac_init_idc = h->pps.cabac ? sl->cabac_init_idc : 0;
+    if (sl->deblocking_filter < 2)
+        slice->disable_deblocking_filter_idc = 1 - sl->deblocking_filter;
+    else
+        slice->disable_deblocking_filter_idc = sl->deblocking_filter;
+    slice->slice_id = h->current_slice - 1;
+}
+
+static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
+                                             DXVA2_DecodeBufferDesc *bs,
+                                             DXVA2_DecodeBufferDesc *sc)
+{
+    const H264Context *h = avctx->priv_data;
+    const unsigned mb_count = h->mb_width * h->mb_height;
+    struct dxva_context *ctx = avctx->hwaccel_context;
+    const H264Picture *current_picture = h->cur_pic_ptr;
+    struct dxva2_picture_context *ctx_pic = 
current_picture->hwaccel_picture_private;
+    DXVA_Slice_H264_Short *slice = NULL;
+    void     *dxva_data_ptr;
+    uint8_t  *dxva_data, *current, *end;
+    unsigned dxva_size;
+    void     *slice_data;
+    unsigned slice_size;
+    unsigned padding;
+    unsigned i;
+
+    /* Create an annex B bitstream buffer with only slice NAL and finalize 
slice */
+    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
+                                              DXVA2_BitStreamDateBufferType,
+                                              &dxva_data_ptr, &dxva_size)))
+        return -1;
+
+    dxva_data = dxva_data_ptr;
+    current = dxva_data;
+    end = dxva_data + dxva_size;
+
+    for (i = 0; i < ctx_pic->slice_count; i++) {
+        static const uint8_t start_code[] = { 0, 0, 1 };
+        static const unsigned start_code_size = sizeof(start_code);
+        unsigned position, size;
+
+        assert(offsetof(DXVA_Slice_H264_Short, BSNALunitDataLocation) ==
+               offsetof(DXVA_Slice_H264_Long,  BSNALunitDataLocation));
+        assert(offsetof(DXVA_Slice_H264_Short, SliceBytesInBuffer) ==
+               offsetof(DXVA_Slice_H264_Long,  SliceBytesInBuffer));
+
+        if (is_slice_short(ctx))
+            slice = &ctx_pic->slice_short[i];
+        else
+            slice = (DXVA_Slice_H264_Short*)&ctx_pic->slice_long[i];
+
+        position = slice->BSNALunitDataLocation;
+        size     = slice->SliceBytesInBuffer;
+        if (start_code_size + size > end - current) {
+            av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream");
+            break;
+        }
+
+        slice->BSNALunitDataLocation = current - dxva_data;
+        slice->SliceBytesInBuffer    = start_code_size + size;
+
+        if (!is_slice_short(ctx)) {
+            DXVA_Slice_H264_Long *slice_long = (DXVA_Slice_H264_Long*)slice;
+            if (i < ctx_pic->slice_count - 1)
+                slice_long->NumMbsForSlice =
+                    slice_long[1].first_mb_in_slice - 
slice_long[0].first_mb_in_slice;
+            else
+                slice_long->NumMbsForSlice = mb_count - 
slice_long->first_mb_in_slice;
+        }
+
+        memcpy(current, start_code, start_code_size);
+        current += start_code_size;
+
+        memcpy(current, &ctx_pic->bitstream[position], size);
+        current += size;
+    }
+    padding = FFMIN(128 - ((current - dxva_data) & 127), end - current);
+    if (slice && padding > 0) {
+        memset(current, 0, padding);
+        current += padding;
+
+        slice->SliceBytesInBuffer += padding;
+    }
+    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
+                                                  
DXVA2_BitStreamDateBufferType)))
+        return -1;
+    if (i < ctx_pic->slice_count)
+        return -1;
+
+    memset(bs, 0, sizeof(*bs));
+    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
+    bs->DataSize             = current - dxva_data;
+    bs->NumMBsInBuffer       = mb_count;
+
+    if (is_slice_short(ctx)) {
+        slice_data = ctx_pic->slice_short;
+        slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short);
+    } else {
+        slice_data = ctx_pic->slice_long;
+        slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_long);
+    }
+    assert((bs->DataSize & 127) == 0);
+    return ff_dxva2_commit_buffer(avctx, ctx, sc,
+                                  DXVA2_SliceControlBufferType,
+                                  slice_data, slice_size, mb_count);
+}
+
+
+static int dxva2_h264_start_frame(AVCodecContext *avctx,
+                                  av_unused const uint8_t *buffer,
+                                  av_unused uint32_t size)
+{
+    const H264Context *h = avctx->priv_data;
+    struct dxva_context *ctx = avctx->hwaccel_context;
+    struct dxva2_picture_context *ctx_pic = 
h->cur_pic_ptr->hwaccel_picture_private;
+
+    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
+        return -1;
+    assert(ctx_pic);
+
+    /* Fill up DXVA_PicParams_H264 */
+    fill_picture_parameters(ctx, h, &ctx_pic->pp);
+
+    /* Fill up DXVA_Qmatrix_H264 */
+    fill_scaling_lists(ctx, h, &ctx_pic->qm);
+
+    ctx_pic->slice_count    = 0;
+    ctx_pic->bitstream_size = 0;
+    ctx_pic->bitstream      = NULL;
+    return 0;
+}
+
+static int dxva2_h264_decode_slice(AVCodecContext *avctx,
+                                   const uint8_t *buffer,
+                                   uint32_t size)
+{
+    const H264Context *h = avctx->priv_data;
+    const H264SliceContext *sl = &h->slice_ctx[0];
+    struct dxva_context *ctx = avctx->hwaccel_context;
+    const H264Picture *current_picture = h->cur_pic_ptr;
+    struct dxva2_picture_context *ctx_pic = 
current_picture->hwaccel_picture_private;
+    unsigned position;
+
+    if (ctx_pic->slice_count >= MAX_SLICES)
+        return -1;
+
+    if (!ctx_pic->bitstream)
+        ctx_pic->bitstream = buffer;
+    ctx_pic->bitstream_size += size;
+
+    position = buffer - ctx_pic->bitstream;
+    if (is_slice_short(ctx))
+        fill_slice_short(&ctx_pic->slice_short[ctx_pic->slice_count],
+                         position, size);
+    else
+        fill_slice_long(avctx, &ctx_pic->slice_long[ctx_pic->slice_count],
+                        &ctx_pic->pp, position, size);
+    ctx_pic->slice_count++;
+
+    if (sl->slice_type != AV_PICTURE_TYPE_I && sl->slice_type != 
AV_PICTURE_TYPE_SI)
+        ctx_pic->pp.wBitFields &= ~(1 << 15); /* Set IntraPicFlag to 0 */
+    return 0;
+}
+
+static int dxva2_h264_end_frame(AVCodecContext *avctx)
+{
+    H264Context *h = avctx->priv_data;
+    H264SliceContext *sl = &h->slice_ctx[0];
+    struct dxva2_picture_context *ctx_pic =
+        h->cur_pic_ptr->hwaccel_picture_private;
+    int ret;
+
+    if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
+        return -1;
+    ret = ff_dxva2_common_end_frame(avctx, h->cur_pic_ptr->f,
+                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
+                                    &ctx_pic->qm, sizeof(ctx_pic->qm),
+                                    commit_bitstream_and_slice_buffer);
+    if (!ret)
+        ff_h264_draw_horiz_band(h, sl, 0, h->avctx->height);
+    return ret;
+}
+
+AVHWAccel ff_h264_dxva2_hwaccel = {
+    .name           = "h264_dxva2",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_H264,
+    .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
+    .start_frame    = dxva2_h264_start_frame,
+    .decode_slice   = dxva2_h264_decode_slice,
+    .end_frame      = dxva2_h264_end_frame,
+    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
+};
diff --git a/libavcodec/dxva_hevc_template.c b/libavcodec/dxva_hevc_template.c
new file mode 100644
index 0000000..932eb50
--- /dev/null
+++ b/libavcodec/dxva_hevc_template.c
@@ -0,0 +1,381 @@
+/*
+ * DXVA2 HEVC HW acceleration.
+ *
+ * copyright (c) 2014 - 2015 Hendrik Leppkes
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/avassert.h"
+
+#include "dxva_internal_template.h"
+#include "hevc.h"
+
+#define MAX_SLICES 256
+
+struct hevc_dxva2_picture_context {
+    DXVA_PicParams_HEVC   pp;
+    DXVA_Qmatrix_HEVC     qm;
+    unsigned              slice_count;
+    DXVA_Slice_HEVC_Short slice_short[MAX_SLICES];
+    const uint8_t         *bitstream;
+    unsigned              bitstream_size;
+};
+
+static void fill_picture_entry(DXVA_PicEntry_HEVC *pic,
+                               unsigned index, unsigned flag)
+{
+    av_assert0((index & 0x7f) == index && (flag & 0x01) == flag);
+    pic->bPicEntry = index | (flag << 7);
+}
+
+static int get_refpic_index(const DXVA_PicParams_HEVC *pp, int surface_index)
+{
+    int i;
+    for (i = 0; i < FF_ARRAY_ELEMS(pp->RefPicList); i++) {
+        if ((pp->RefPicList[i].bPicEntry & 0x7f) == surface_index)
+          return i;
+    }
+    return 0xff;
+}
+
+static void fill_picture_parameters(struct dxva_context *ctx, const 
HEVCContext *h,
+                                    DXVA_PicParams_HEVC *pp)
+{
+    const HEVCFrame *current_picture = h->ref;
+    int i, j, k;
+
+    memset(pp, 0, sizeof(*pp));
+
+    pp->PicWidthInMinCbsY  = h->sps->min_cb_width;
+    pp->PicHeightInMinCbsY = h->sps->min_cb_height;
+
+    pp->wFormatAndSequenceInfoFlags = (h->sps->chroma_format_idc          <<  
0) |
+                                      (h->sps->separate_colour_plane_flag <<  
2) |
+                                      ((h->sps->bit_depth - 8)            <<  
3) |
+                                      ((h->sps->bit_depth - 8)            <<  
6) |
+                                      ((h->sps->log2_max_poc_lsb - 4)     <<  
9) |
+                                      (0                                  << 
13) |
+                                      (0                                  << 
14) |
+                                      (0                                  << 
15);
+
+    fill_picture_entry(&pp->CurrPic, ff_dxva2_get_surface_index(ctx, 
current_picture->frame), 0);
+
+    pp->sps_max_dec_pic_buffering_minus1         = 
h->sps->temporal_layer[h->sps->max_sub_layers - 1].max_dec_pic_buffering - 1;
+    pp->log2_min_luma_coding_block_size_minus3   = h->sps->log2_min_cb_size - 
3;
+    pp->log2_diff_max_min_luma_coding_block_size = 
h->sps->log2_diff_max_min_coding_block_size;
+    pp->log2_min_transform_block_size_minus2     = h->sps->log2_min_tb_size - 
2;
+    pp->log2_diff_max_min_transform_block_size   = h->sps->log2_max_trafo_size 
 - h->sps->log2_min_tb_size;
+    pp->max_transform_hierarchy_depth_inter      = 
h->sps->max_transform_hierarchy_depth_inter;
+    pp->max_transform_hierarchy_depth_intra      = 
h->sps->max_transform_hierarchy_depth_intra;
+    pp->num_short_term_ref_pic_sets              = h->sps->nb_st_rps;
+    pp->num_long_term_ref_pics_sps               = 
h->sps->num_long_term_ref_pics_sps;
+
+    pp->num_ref_idx_l0_default_active_minus1     = 
h->pps->num_ref_idx_l0_default_active - 1;
+    pp->num_ref_idx_l1_default_active_minus1     = 
h->pps->num_ref_idx_l1_default_active - 1;
+    pp->init_qp_minus26                          = h->pps->pic_init_qp_minus26;
+
+    if (h->sh.short_term_ref_pic_set_sps_flag == 0 && h->sh.short_term_rps) {
+        pp->ucNumDeltaPocsOfRefRpsIdx            = 
h->sh.short_term_rps->num_delta_pocs;
+        pp->wNumBitsForShortTermRPSInSlice       = 
h->sh.short_term_ref_pic_set_size;
+    }
+
+    pp->dwCodingParamToolFlags = (h->sps->scaling_list_enable_flag             
  <<  0) |
+                                 (h->sps->amp_enabled_flag                     
  <<  1) |
+                                 (h->sps->sao_enabled                          
  <<  2) |
+                                 (h->sps->pcm_enabled_flag                     
  <<  3) |
+                                 ((h->sps->pcm_enabled_flag ? 
(h->sps->pcm.bit_depth - 1) : 0)            <<  4) |
+                                 ((h->sps->pcm_enabled_flag ? 
(h->sps->pcm.bit_depth_chroma - 1) : 0)     <<  8) |
+                                 ((h->sps->pcm_enabled_flag ? 
(h->sps->pcm.log2_min_pcm_cb_size - 3) : 0) << 12) |
+                                 ((h->sps->pcm_enabled_flag ? 
(h->sps->pcm.log2_max_pcm_cb_size - h->sps->pcm.log2_min_pcm_cb_size) : 0) << 
14) |
+                                 (h->sps->pcm.loop_filter_disable_flag         
  << 16) |
+                                 (h->sps->long_term_ref_pics_present_flag      
  << 17) |
+                                 (h->sps->sps_temporal_mvp_enabled_flag        
  << 18) |
+                                 
(h->sps->sps_strong_intra_smoothing_enable_flag << 19) |
+                                 
(h->pps->dependent_slice_segments_enabled_flag  << 20) |
+                                 (h->pps->output_flag_present_flag             
  << 21) |
+                                 (h->pps->num_extra_slice_header_bits          
  << 22) |
+                                 (h->pps->sign_data_hiding_flag                
  << 25) |
+                                 (h->pps->cabac_init_present_flag              
  << 26) |
+                                 (0                                            
  << 27);
+
+    pp->dwCodingSettingPicturePropertyFlags = 
(h->pps->constrained_intra_pred_flag                <<  0) |
+                                              
(h->pps->transform_skip_enabled_flag                <<  1) |
+                                              
(h->pps->cu_qp_delta_enabled_flag                   <<  2) |
+                                              
(h->pps->pic_slice_level_chroma_qp_offsets_present_flag <<  3) |
+                                              (h->pps->weighted_pred_flag      
                   <<  4) |
+                                              (h->pps->weighted_bipred_flag    
                   <<  5) |
+                                              
(h->pps->transquant_bypass_enable_flag              <<  6) |
+                                              (h->pps->tiles_enabled_flag      
                   <<  7) |
+                                              
(h->pps->entropy_coding_sync_enabled_flag           <<  8) |
+                                              (h->pps->uniform_spacing_flag    
                   <<  9) |
+                                              ((h->pps->tiles_enabled_flag ? 
h->pps->loop_filter_across_tiles_enabled_flag : 0) << 10) |
+                                              
(h->pps->seq_loop_filter_across_slices_enabled_flag << 11) |
+                                              
(h->pps->deblocking_filter_override_enabled_flag    << 12) |
+                                              (h->pps->disable_dbf             
                   << 13) |
+                                              
(h->pps->lists_modification_present_flag            << 14) |
+                                              
(h->pps->slice_header_extension_present_flag        << 15) |
+                                              (IS_IRAP(h)                      
                   << 16) |
+                                              (IS_IDR(h)                       
                   << 17) |
+                                              /* IntraPicFlag */
+                                              (IS_IRAP(h)                      
                   << 18) |
+                                              (0                               
                   << 19);
+    pp->pps_cb_qp_offset            = h->pps->cb_qp_offset;
+    pp->pps_cr_qp_offset            = h->pps->cr_qp_offset;
+    if (h->pps->tiles_enabled_flag) {
+        pp->num_tile_columns_minus1 = h->pps->num_tile_columns - 1;
+        pp->num_tile_rows_minus1    = h->pps->num_tile_rows - 1;
+
+        if (!h->pps->uniform_spacing_flag) {
+            for (i = 0; i < h->pps->num_tile_columns; i++)
+                pp->column_width_minus1[i] = h->pps->column_width[i] - 1;
+
+            for (i = 0; i < h->pps->num_tile_rows; i++)
+                pp->row_height_minus1[i] = h->pps->row_height[i] - 1;
+        }
+    }
+
+    pp->diff_cu_qp_delta_depth           = h->pps->diff_cu_qp_delta_depth;
+    pp->pps_beta_offset_div2             = h->pps->beta_offset / 2;
+    pp->pps_tc_offset_div2               = h->pps->tc_offset / 2;
+    pp->log2_parallel_merge_level_minus2 = h->pps->log2_parallel_merge_level - 
2;
+    pp->CurrPicOrderCntVal               = h->poc;
+
+    // empty the lists
+    memset(&pp->RefPicList, 0xff, sizeof(pp->RefPicList));
+    memset(&pp->RefPicSetStCurrBefore, 0xff, 
sizeof(pp->RefPicSetStCurrBefore));
+    memset(&pp->RefPicSetStCurrAfter, 0xff, sizeof(pp->RefPicSetStCurrAfter));
+    memset(&pp->RefPicSetLtCurr, 0xff, sizeof(pp->RefPicSetLtCurr));
+
+    // fill RefPicList from the DPB
+    for (i = 0, j = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) {
+        const HEVCFrame *frame = &h->DPB[i];
+        if (frame != current_picture && (frame->flags & 
(HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) {
+            fill_picture_entry(&pp->RefPicList[j], 
ff_dxva2_get_surface_index(ctx, frame->frame), !!(frame->flags & 
HEVC_FRAME_FLAG_LONG_REF));
+            pp->PicOrderCntValList[j] = frame->poc;
+            j++;
+        }
+    }
+
+    #define DO_REF_LIST(ref_idx, ref_list) { \
+        const RefPicList *rpl = &h->rps[ref_idx]; \
+        av_assert0(rpl->nb_refs <= FF_ARRAY_ELEMS(pp->ref_list)); \
+        for (j = 0, k = 0; j < rpl->nb_refs; j++) { \
+            if (rpl->ref[j]) { \
+                pp->ref_list[k] = get_refpic_index(pp, 
ff_dxva2_get_surface_index(ctx, rpl->ref[j]->frame)); \
+                k++; \
+            } \
+        } \
+    }
+
+    // Fill short term and long term lists
+    DO_REF_LIST(ST_CURR_BEF, RefPicSetStCurrBefore);
+    DO_REF_LIST(ST_CURR_AFT, RefPicSetStCurrAfter);
+    DO_REF_LIST(LT_CURR, RefPicSetLtCurr);
+
+    pp->StatusReportFeedbackNumber = 1 + ctx->report_id++;
+}
+
+static void fill_scaling_lists(struct dxva_context *ctx, const HEVCContext *h, 
DXVA_Qmatrix_HEVC *qm)
+{
+    unsigned i, j, pos;
+    const ScalingList *sl = h->pps->scaling_list_data_present_flag ?
+                            &h->pps->scaling_list : &h->sps->scaling_list;
+
+    memset(qm, 0, sizeof(*qm));
+    for (i = 0; i < 6; i++) {
+        for (j = 0; j < 16; j++) {
+            pos = 4 * ff_hevc_diag_scan4x4_y[j] + ff_hevc_diag_scan4x4_x[j];
+            qm->ucScalingLists0[i][j] = sl->sl[0][i][pos];
+        }
+
+        for (j = 0; j < 64; j++) {
+            pos = 8 * ff_hevc_diag_scan8x8_y[j] + ff_hevc_diag_scan8x8_x[j];
+            qm->ucScalingLists1[i][j] = sl->sl[1][i][pos];
+            qm->ucScalingLists2[i][j] = sl->sl[2][i][pos];
+
+            if (i < 2)
+                qm->ucScalingLists3[i][j] = sl->sl[3][i][pos];
+        }
+
+        qm->ucScalingListDCCoefSizeID2[i] = sl->sl_dc[0][i];
+        if (i < 2)
+            qm->ucScalingListDCCoefSizeID3[i] = sl->sl_dc[1][i];
+    }
+}
+
+static void fill_slice_short(DXVA_Slice_HEVC_Short *slice,
+                             unsigned position, unsigned size)
+{
+    memset(slice, 0, sizeof(*slice));
+    slice->BSNALunitDataLocation = position;
+    slice->SliceBytesInBuffer    = size;
+    slice->wBadSliceChopping     = 0;
+}
+
+static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
+                                             DXVA2_DecodeBufferDesc *bs,
+                                             DXVA2_DecodeBufferDesc *sc)
+{
+    const HEVCContext *h = avctx->priv_data;
+    struct dxva_context *ctx = avctx->hwaccel_context;
+    const HEVCFrame *current_picture = h->ref;
+    struct hevc_dxva2_picture_context *ctx_pic = 
current_picture->hwaccel_picture_private;
+    DXVA_Slice_HEVC_Short *slice = NULL;
+    void     *dxva_data_ptr;
+    uint8_t  *dxva_data, *current, *end;
+    unsigned dxva_size;
+    void     *slice_data;
+    unsigned slice_size;
+    unsigned padding;
+    unsigned i;
+
+    /* Create an annex B bitstream buffer with only slice NAL and finalize 
slice */
+    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
+                                              DXVA2_BitStreamDateBufferType,
+                                              &dxva_data_ptr, &dxva_size)))
+        return -1;
+
+    dxva_data = dxva_data_ptr;
+    current = dxva_data;
+    end = dxva_data + dxva_size;
+
+    for (i = 0; i < ctx_pic->slice_count; i++) {
+        static const uint8_t start_code[] = { 0, 0, 1 };
+        static const unsigned start_code_size = sizeof(start_code);
+        unsigned position, size;
+
+        slice = &ctx_pic->slice_short[i];
+
+        position = slice->BSNALunitDataLocation;
+        size     = slice->SliceBytesInBuffer;
+        if (start_code_size + size > end - current) {
+            av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream");
+            break;
+        }
+
+        slice->BSNALunitDataLocation = current - dxva_data;
+        slice->SliceBytesInBuffer    = start_code_size + size;
+
+        memcpy(current, start_code, start_code_size);
+        current += start_code_size;
+
+        memcpy(current, &ctx_pic->bitstream[position], size);
+        current += size;
+    }
+    padding = FFMIN(128 - ((current - dxva_data) & 127), end - current);
+    if (slice && padding > 0) {
+        memset(current, 0, padding);
+        current += padding;
+
+        slice->SliceBytesInBuffer += padding;
+    }
+    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
+                                                  
DXVA2_BitStreamDateBufferType)))
+        return -1;
+    if (i < ctx_pic->slice_count)
+        return -1;
+
+    memset(bs, 0, sizeof(*bs));
+    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
+    bs->DataSize             = current - dxva_data;
+    bs->NumMBsInBuffer       = 0;
+
+    slice_data = ctx_pic->slice_short;
+    slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short);
+
+    av_assert0((bs->DataSize & 127) == 0);
+    return ff_dxva2_commit_buffer(avctx, ctx, sc,
+                                  DXVA2_SliceControlBufferType,
+                                  slice_data, slice_size, 0);
+}
+
+
+static int dxva2_hevc_start_frame(AVCodecContext *avctx,
+                                  av_unused const uint8_t *buffer,
+                                  av_unused uint32_t size)
+{
+    const HEVCContext *h = avctx->priv_data;
+    struct dxva_context *ctx = avctx->hwaccel_context;
+    struct hevc_dxva2_picture_context *ctx_pic = 
h->ref->hwaccel_picture_private;
+
+    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
+        return -1;
+    av_assert0(ctx_pic);
+
+    /* Fill up DXVA_PicParams_HEVC */
+    fill_picture_parameters(ctx, h, &ctx_pic->pp);
+
+    /* Fill up DXVA_Qmatrix_HEVC */
+    fill_scaling_lists(ctx, h, &ctx_pic->qm);
+
+    ctx_pic->slice_count    = 0;
+    ctx_pic->bitstream_size = 0;
+    ctx_pic->bitstream      = NULL;
+    return 0;
+}
+
+static int dxva2_hevc_decode_slice(AVCodecContext *avctx,
+                                   const uint8_t *buffer,
+                                   uint32_t size)
+{
+    const HEVCContext *h = avctx->priv_data;
+    const HEVCFrame *current_picture = h->ref;
+    struct hevc_dxva2_picture_context *ctx_pic = 
current_picture->hwaccel_picture_private;
+    unsigned position;
+
+    if (ctx_pic->slice_count >= MAX_SLICES)
+        return -1;
+
+    if (!ctx_pic->bitstream)
+        ctx_pic->bitstream = buffer;
+    ctx_pic->bitstream_size += size;
+
+    position = buffer - ctx_pic->bitstream;
+    fill_slice_short(&ctx_pic->slice_short[ctx_pic->slice_count], position, 
size);
+    ctx_pic->slice_count++;
+
+    return 0;
+}
+
+static int dxva2_hevc_end_frame(AVCodecContext *avctx)
+{
+    HEVCContext *h = avctx->priv_data;
+    struct hevc_dxva2_picture_context *ctx_pic = 
h->ref->hwaccel_picture_private;
+    int scale = ctx_pic->pp.dwCodingParamToolFlags & 1;
+    int ret;
+
+    if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
+        return -1;
+
+    ret = ff_dxva2_common_end_frame(avctx, h->ref->frame,
+                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
+                                    scale ? &ctx_pic->qm : NULL, scale ? 
sizeof(ctx_pic->qm) : 0,
+                                    commit_bitstream_and_slice_buffer);
+    return ret;
+}
+
+AVHWAccel ff_hevc_dxva2_hwaccel = {
+    .name           = "hevc_dxva2",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_HEVC,
+    .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
+    .start_frame    = dxva2_hevc_start_frame,
+    .decode_slice   = dxva2_hevc_decode_slice,
+    .end_frame      = dxva2_hevc_end_frame,
+    .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
+};
diff --git a/libavcodec/dxva_internal_template.h 
b/libavcodec/dxva_internal_template.h
new file mode 100644
index 0000000..7f19b7c
--- /dev/null
+++ b/libavcodec/dxva_internal_template.h
@@ -0,0 +1,56 @@
+/*
+ * DXVA2 HW acceleration
+ *
+ * copyright (c) 2010 Laurent Aimar
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_DXVA_INTERNAL_TEMPLATE_H
+#define AVCODEC_DXVA_INTERNAL_TEMPLATE_H
+
+#define COBJMACROS
+
+#include "config.h"
+
+#include "dxva2.h"
+#if HAVE_DXVA_H
+#include <dxva.h>
+#endif
+
+#include "avcodec.h"
+#include "mpegvideo.h"
+
+void *ff_dxva2_get_surface(const AVFrame *frame);
+
+unsigned ff_dxva2_get_surface_index(const struct dxva_context *,
+                                    const AVFrame *frame);
+
+int ff_dxva2_commit_buffer(AVCodecContext *, struct dxva_context *,
+                           DXVA2_DecodeBufferDesc *,
+                           unsigned type, const void *data, unsigned size,
+                           unsigned mb_count);
+
+
+int ff_dxva2_common_end_frame(AVCodecContext *, AVFrame *,
+                              const void *pp, unsigned pp_size,
+                              const void *qm, unsigned qm_size,
+                              int (*commit_bs_si)(AVCodecContext *,
+                                                  DXVA2_DecodeBufferDesc *bs,
+                                                  DXVA2_DecodeBufferDesc 
*slice));
+
+#endif /* AVCODEC_DXVA_INTERNAL_TEMPLATE_H */
diff --git a/libavcodec/dxva_mpeg2_template.c b/libavcodec/dxva_mpeg2_template.c
new file mode 100644
index 0000000..a77a9ee
--- /dev/null
+++ b/libavcodec/dxva_mpeg2_template.c
@@ -0,0 +1,283 @@
+/*
+ * MPEG-2 HW acceleration.
+ *
+ * copyright (c) 2010 Laurent Aimar
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/log.h"
+#include "dxva_internal_template.h"
+#include "mpegutils.h"
+
+#define MAX_SLICES 1024
+struct dxva2_picture_context {
+    DXVA_PictureParameters pp;
+    DXVA_QmatrixData       qm;
+    unsigned               slice_count;
+    DXVA_SliceInfo         slice[MAX_SLICES];
+
+    const uint8_t          *bitstream;
+    unsigned               bitstream_size;
+};
+
+static void fill_picture_parameters(AVCodecContext *avctx,
+                                    struct dxva_context *ctx,
+                                    const struct MpegEncContext *s,
+                                    DXVA_PictureParameters *pp)
+{
+    const Picture *current_picture = s->current_picture_ptr;
+    int is_field = s->picture_structure != PICT_FRAME;
+
+    memset(pp, 0, sizeof(*pp));
+    pp->wDecodedPictureIndex         = ff_dxva2_get_surface_index(ctx, 
current_picture->f);
+    pp->wDeblockedPictureIndex       = 0;
+    if (s->pict_type != AV_PICTURE_TYPE_I)
+        pp->wForwardRefPictureIndex  = ff_dxva2_get_surface_index(ctx, 
s->last_picture.f);
+    else
+        pp->wForwardRefPictureIndex  = 0xffff;
+    if (s->pict_type == AV_PICTURE_TYPE_B)
+        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, 
s->next_picture.f);
+    else
+        pp->wBackwardRefPictureIndex = 0xffff;
+    pp->wPicWidthInMBminus1          = s->mb_width  - 1;
+    pp->wPicHeightInMBminus1         = (s->mb_height >> is_field) - 1;
+    pp->bMacroblockWidthMinus1       = 15;
+    pp->bMacroblockHeightMinus1      = 15;
+    pp->bBlockWidthMinus1            = 7;
+    pp->bBlockHeightMinus1           = 7;
+    pp->bBPPminus1                   = 7;
+    pp->bPicStructure                = s->picture_structure;
+    pp->bSecondField                 = is_field && !s->first_field;
+    pp->bPicIntra                    = s->pict_type == AV_PICTURE_TYPE_I;
+    pp->bPicBackwardPrediction       = s->pict_type == AV_PICTURE_TYPE_B;
+    pp->bBidirectionalAveragingMode  = 0;
+    pp->bMVprecisionAndChromaRelation= 0; /* FIXME */
+    pp->bChromaFormat                = s->chroma_format;
+    pp->bPicScanFixed                = 1;
+    pp->bPicScanMethod               = s->alternate_scan ? 1 : 0;
+    pp->bPicReadbackRequests         = 0;
+    pp->bRcontrol                    = 0;
+    pp->bPicSpatialResid8            = 0;
+    pp->bPicOverflowBlocks           = 0;
+    pp->bPicExtrapolation            = 0;
+    pp->bPicDeblocked                = 0;
+    pp->bPicDeblockConfined          = 0;
+    pp->bPic4MVallowed               = 0;
+    pp->bPicOBMC                     = 0;
+    pp->bPicBinPB                    = 0;
+    pp->bMV_RPS                      = 0;
+    pp->bReservedBits                = 0;
+    pp->wBitstreamFcodes             = (s->mpeg_f_code[0][0] << 12) |
+                                       (s->mpeg_f_code[0][1] <<  8) |
+                                       (s->mpeg_f_code[1][0] <<  4) |
+                                       (s->mpeg_f_code[1][1]      );
+    pp->wBitstreamPCEelements        = (s->intra_dc_precision         << 14) |
+                                       (s->picture_structure          << 12) |
+                                       (s->top_field_first            << 11) |
+                                       (s->frame_pred_frame_dct       << 10) |
+                                       (s->concealment_motion_vectors <<  9) |
+                                       (s->q_scale_type               <<  8) |
+                                       (s->intra_vlc_format           <<  7) |
+                                       (s->alternate_scan             <<  6) |
+                                       (s->repeat_first_field         <<  5) |
+                                       (s->chroma_420_type            <<  4) |
+                                       (s->progressive_frame          <<  3);
+    pp->bBitstreamConcealmentNeed    = 0;
+    pp->bBitstreamConcealmentMethod  = 0;
+}
+
+static void fill_quantization_matrices(AVCodecContext *avctx,
+                                       struct dxva_context *ctx,
+                                       const struct MpegEncContext *s,
+                                       DXVA_QmatrixData *qm)
+{
+    int i;
+    for (i = 0; i < 4; i++)
+        qm->bNewQmatrix[i] = 1;
+    for (i = 0; i < 64; i++) {
+        int n = s->idsp.idct_permutation[ff_zigzag_direct[i]];
+        qm->Qmatrix[0][i] = s->intra_matrix[n];;
+        qm->Qmatrix[1][i] = s->inter_matrix[n];;
+        qm->Qmatrix[2][i] = s->chroma_intra_matrix[n];;
+        qm->Qmatrix[3][i] = s->chroma_inter_matrix[n];;
+    }
+}
+
+static void fill_slice(AVCodecContext *avctx,
+                       const struct MpegEncContext *s,
+                       DXVA_SliceInfo *slice,
+                       unsigned position,
+                       const uint8_t *buffer, unsigned size)
+{
+    int is_field = s->picture_structure != PICT_FRAME;
+    GetBitContext gb;
+
+    memset(slice, 0, sizeof(*slice));
+    slice->wHorizontalPosition = s->mb_x;
+    slice->wVerticalPosition   = s->mb_y >> is_field;
+    slice->dwSliceBitsInBuffer = 8 * size;
+    slice->dwSliceDataLocation = position;
+    slice->bStartCodeBitOffset = 0;
+    slice->bReservedBits       = 0;
+    /* XXX We store the index of the first MB and it will be fixed later */
+    slice->wNumberMBsInSlice   = (s->mb_y >> is_field) * s->mb_width + s->mb_x;
+    slice->wBadSliceChopping   = 0;
+
+    init_get_bits(&gb, &buffer[4], 8 * (size - 4));
+
+    slice->wQuantizerScaleCode = get_bits(&gb, 5);
+    while (get_bits1(&gb))
+        skip_bits(&gb, 8);
+
+    slice->wMBbitOffset        = 4 * 8 + get_bits_count(&gb);
+}
+static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
+                                             DXVA2_DecodeBufferDesc *bs,
+                                             DXVA2_DecodeBufferDesc *sc)
+{
+    const struct MpegEncContext *s = avctx->priv_data;
+    struct dxva_context *ctx = avctx->hwaccel_context;
+    struct dxva2_picture_context *ctx_pic =
+        s->current_picture_ptr->hwaccel_picture_private;
+    const int is_field = s->picture_structure != PICT_FRAME;
+    const unsigned mb_count = s->mb_width * (s->mb_height >> is_field);
+    void     *dxva_data_ptr;
+    uint8_t  *dxva_data, *current, *end;
+    unsigned dxva_size;
+    unsigned i;
+
+    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
+                                              DXVA2_BitStreamDateBufferType,
+                                              &dxva_data_ptr, &dxva_size)))
+        return -1;
+
+    dxva_data = dxva_data_ptr;
+    current = dxva_data;
+    end = dxva_data + dxva_size;
+
+    for (i = 0; i < ctx_pic->slice_count; i++) {
+        DXVA_SliceInfo *slice = &ctx_pic->slice[i];
+        unsigned position = slice->dwSliceDataLocation;
+        unsigned size     = slice->dwSliceBitsInBuffer / 8;
+        if (size > end - current) {
+            av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream");
+            break;
+        }
+        slice->dwSliceDataLocation = current - dxva_data;
+
+        if (i < ctx_pic->slice_count - 1)
+            slice->wNumberMBsInSlice =
+                slice[1].wNumberMBsInSlice - slice[0].wNumberMBsInSlice;
+        else
+            slice->wNumberMBsInSlice =
+                mb_count - slice[0].wNumberMBsInSlice;
+
+        memcpy(current, &ctx_pic->bitstream[position], size);
+        current += size;
+    }
+    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
+                                                  
DXVA2_BitStreamDateBufferType)))
+        return -1;
+    if (i < ctx_pic->slice_count)
+        return -1;
+
+    memset(bs, 0, sizeof(*bs));
+    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
+    bs->DataSize             = current - dxva_data;
+    bs->NumMBsInBuffer       = mb_count;
+
+    return ff_dxva2_commit_buffer(avctx, ctx, sc,
+                                  DXVA2_SliceControlBufferType,
+                                  ctx_pic->slice,
+                                  ctx_pic->slice_count * 
sizeof(*ctx_pic->slice),
+                                  mb_count);
+}
+
+static int dxva2_mpeg2_start_frame(AVCodecContext *avctx,
+                                   av_unused const uint8_t *buffer,
+                                   av_unused uint32_t size)
+{
+    const struct MpegEncContext *s = avctx->priv_data;
+    struct dxva_context *ctx = avctx->hwaccel_context;
+    struct dxva2_picture_context *ctx_pic =
+        s->current_picture_ptr->hwaccel_picture_private;
+
+    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
+        return -1;
+    assert(ctx_pic);
+
+    fill_picture_parameters(avctx, ctx, s, &ctx_pic->pp);
+    fill_quantization_matrices(avctx, ctx, s, &ctx_pic->qm);
+
+    ctx_pic->slice_count    = 0;
+    ctx_pic->bitstream_size = 0;
+    ctx_pic->bitstream      = NULL;
+    return 0;
+}
+
+static int dxva2_mpeg2_decode_slice(AVCodecContext *avctx,
+                                    const uint8_t *buffer, uint32_t size)
+{
+    const struct MpegEncContext *s = avctx->priv_data;
+    struct dxva2_picture_context *ctx_pic =
+        s->current_picture_ptr->hwaccel_picture_private;
+    unsigned position;
+
+    if (ctx_pic->slice_count >= MAX_SLICES) {
+        avpriv_request_sample(avctx, "%d slices in dxva2",
+                              ctx_pic->slice_count);
+        return -1;
+    }
+    if (!ctx_pic->bitstream)
+        ctx_pic->bitstream = buffer;
+    ctx_pic->bitstream_size += size;
+
+    position = buffer - ctx_pic->bitstream;
+    fill_slice(avctx, s, &ctx_pic->slice[ctx_pic->slice_count++], position,
+               buffer, size);
+    return 0;
+}
+
+static int dxva2_mpeg2_end_frame(AVCodecContext *avctx)
+{
+    struct MpegEncContext *s = avctx->priv_data;
+    struct dxva2_picture_context *ctx_pic =
+        s->current_picture_ptr->hwaccel_picture_private;
+    int ret;
+
+    if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
+        return -1;
+    ret = ff_dxva2_common_end_frame(avctx, s->current_picture_ptr->f,
+                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
+                                    &ctx_pic->qm, sizeof(ctx_pic->qm),
+                                    commit_bitstream_and_slice_buffer);
+    if (!ret)
+        ff_mpeg_draw_horiz_band(s, 0, avctx->height);
+    return ret;
+}
+
+AVHWAccel ff_mpeg2_dxva2_hwaccel = {
+    .name           = "mpeg2_dxva2",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MPEG2VIDEO,
+    .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
+    .start_frame    = dxva2_mpeg2_start_frame,
+    .decode_slice   = dxva2_mpeg2_decode_slice,
+    .end_frame      = dxva2_mpeg2_end_frame,
+    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
+};
diff --git a/libavcodec/dxva_template.c b/libavcodec/dxva_template.c
new file mode 100644
index 0000000..2504b3c
--- /dev/null
+++ b/libavcodec/dxva_template.c
@@ -0,0 +1,174 @@
+/*
+ * DXVA2 HW acceleration.
+ *
+ * copyright (c) 2010 Laurent Aimar
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "libavutil/log.h"
+#include "libavutil/time.h"
+
+#include "avcodec.h"
+#include "mpegvideo.h"
+#include "dxva_internal_template.h"
+
+void *ff_dxva2_get_surface(const AVFrame *frame)
+{
+    return frame->data[3];
+}
+
+unsigned ff_dxva2_get_surface_index(const struct dxva_context *ctx,
+                                    const AVFrame *frame)
+{
+    void *surface = ff_dxva2_get_surface(frame);
+    unsigned i;
+
+    for (i = 0; i < ctx->surface_count; i++)
+        if (ctx->surface[i] == surface)
+            return i;
+
+    assert(0);
+    return 0;
+}
+
+int ff_dxva2_commit_buffer(AVCodecContext *avctx,
+                           struct dxva_context *ctx,
+                           DXVA2_DecodeBufferDesc *dsc,
+                           unsigned type, const void *data, unsigned size,
+                           unsigned mb_count)
+{
+    void     *dxva_data;
+    unsigned dxva_size;
+    int      result;
+    HRESULT hr;
+
+    hr = IDirectXVideoDecoder_GetBuffer(ctx->decoder, type,
+                                        &dxva_data, &dxva_size);
+    if (FAILED(hr)) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %u: 0x%lx\n",
+               type, hr);
+        return -1;
+    }
+    if (size <= dxva_size) {
+        memcpy(dxva_data, data, size);
+
+        memset(dsc, 0, sizeof(*dsc));
+        dsc->CompressedBufferType = type;
+        dsc->DataSize             = size;
+        dsc->NumMBsInBuffer       = mb_count;
+
+        result = 0;
+    } else {
+        av_log(avctx, AV_LOG_ERROR, "Buffer for type %u was too small\n", 
type);
+        result = -1;
+    }
+
+    hr = IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, type);
+    if (FAILED(hr)) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Failed to release buffer type %u: 0x%lx\n",
+               type, hr);
+        result = -1;
+    }
+    return result;
+}
+
+int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
+                              const void *pp, unsigned pp_size,
+                              const void *qm, unsigned qm_size,
+                              int (*commit_bs_si)(AVCodecContext *,
+                                                  DXVA2_DecodeBufferDesc *bs,
+                                                  DXVA2_DecodeBufferDesc 
*slice))
+{
+    struct dxva_context *ctx = avctx->hwaccel_context;
+    unsigned               buffer_count = 0;
+    DXVA2_DecodeBufferDesc buffer[4];
+    DXVA2_DecodeExecuteParams exec = { 0 };
+    int result, runs = 0;
+    HRESULT hr;
+
+    do {
+        hr = IDirectXVideoDecoder_BeginFrame(ctx->decoder,
+                                             ff_dxva2_get_surface(frame),
+                                             NULL);
+        if (hr == E_PENDING)
+            av_usleep(2000);
+    } while (hr == E_PENDING && ++runs < 50);
+
+    if (FAILED(hr)) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to begin frame: 0x%lx\n", hr);
+        return -1;
+    }
+
+    result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
+                                    DXVA2_PictureParametersBufferType,
+                                    pp, pp_size, 0);
+    if (result) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Failed to add picture parameter buffer\n");
+        goto end;
+    }
+    buffer_count++;
+
+    if (qm_size > 0) {
+        result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
+                                        
DXVA2_InverseQuantizationMatrixBufferType,
+                                        qm, qm_size, 0);
+        if (result) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Failed to add inverse quantization matrix buffer\n");
+            goto end;
+        }
+        buffer_count++;
+    }
+
+    result = commit_bs_si(avctx,
+                          &buffer[buffer_count + 0],
+                          &buffer[buffer_count + 1]);
+    if (result) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Failed to add bitstream or slice control buffer\n");
+        goto end;
+    }
+    buffer_count += 2;
+
+    /* TODO Film Grain when possible */
+
+    assert(buffer_count == 1 + (qm_size > 0) + 2);
+
+    exec.NumCompBuffers      = buffer_count;
+    exec.pCompressedBuffers  = buffer;
+    exec.pExtensionData      = NULL;
+    hr = IDirectXVideoDecoder_Execute(ctx->decoder, &exec);
+    if (FAILED(hr)) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to execute: 0x%lx\n", hr);
+        result = -1;
+    }
+
+end:
+    hr = IDirectXVideoDecoder_EndFrame(ctx->decoder, NULL);
+    if (FAILED(hr)) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to end frame: 0x%lx\n", hr);
+        result = -1;
+    }
+
+    return result;
+}
diff --git a/libavcodec/dxva_vc1_template.c b/libavcodec/dxva_vc1_template.c
new file mode 100644
index 0000000..a2049ac
--- /dev/null
+++ b/libavcodec/dxva_vc1_template.c
@@ -0,0 +1,297 @@
+/*
+ * DXVA2 WMV3/VC-1 HW acceleration.
+ *
+ * copyright (c) 2010 Laurent Aimar
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "dxva_internal_template.h"
+#include "mpegutils.h"
+#include "vc1.h"
+#include "vc1data.h"
+
+struct dxva2_picture_context {
+    DXVA_PictureParameters pp;
+    DXVA_SliceInfo         si;
+
+    const uint8_t          *bitstream;
+    unsigned               bitstream_size;
+};
+
+static void fill_picture_parameters(AVCodecContext *avctx,
+                                    struct dxva_context *ctx, const VC1Context 
*v,
+                                    DXVA_PictureParameters *pp)
+{
+    const MpegEncContext *s = &v->s;
+    const Picture *current_picture = s->current_picture_ptr;
+
+    memset(pp, 0, sizeof(*pp));
+    pp->wDecodedPictureIndex    =
+    pp->wDeblockedPictureIndex  = ff_dxva2_get_surface_index(ctx, 
current_picture->f);
+    if (s->pict_type != AV_PICTURE_TYPE_I && !v->bi_type)
+        pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, 
s->last_picture.f);
+    else
+        pp->wForwardRefPictureIndex = 0xffff;
+    if (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type)
+        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, 
s->next_picture.f);
+    else
+        pp->wBackwardRefPictureIndex = 0xffff;
+    if (v->profile == PROFILE_ADVANCED) {
+        /* It is the cropped width/height -1 of the frame */
+        pp->wPicWidthInMBminus1 = avctx->width  - 1;
+        pp->wPicHeightInMBminus1= avctx->height - 1;
+    } else {
+        /* It is the coded width/height in macroblock -1 of the frame */
+        pp->wPicWidthInMBminus1 = s->mb_width  - 1;
+        pp->wPicHeightInMBminus1= s->mb_height - 1;
+    }
+    pp->bMacroblockWidthMinus1  = 15;
+    pp->bMacroblockHeightMinus1 = 15;
+    pp->bBlockWidthMinus1       = 7;
+    pp->bBlockHeightMinus1      = 7;
+    pp->bBPPminus1              = 7;
+    if (s->picture_structure & PICT_TOP_FIELD)
+        pp->bPicStructure      |= 0x01;
+    if (s->picture_structure & PICT_BOTTOM_FIELD)
+        pp->bPicStructure      |= 0x02;
+    pp->bSecondField            = v->interlace && v->fcm != ILACE_FIELD && 
!s->first_field;
+    pp->bPicIntra               = s->pict_type == AV_PICTURE_TYPE_I || 
v->bi_type;
+    pp->bPicBackwardPrediction  = s->pict_type == AV_PICTURE_TYPE_B && 
!v->bi_type;
+    pp->bBidirectionalAveragingMode = (1                                       
    << 7) |
+                                      ((ctx->cfg->ConfigIntraResidUnsigned != 
0)   << 6) |
+                                      ((ctx->cfg->ConfigResidDiffAccelerator 
!= 0) << 5) |
+                                      ((v->lumscale != 32 || v->lumshift != 0) 
    << 4) |
+                                      ((v->profile == PROFILE_ADVANCED)        
    << 3);
+    pp->bMVprecisionAndChromaRelation = ((v->mv_mode == 
MV_PMODE_1MV_HPEL_BILIN) << 3) |
+                                        (1                                     
  << 2) |
+                                        (0                                     
  << 1) |
+                                        (!s->quarter_sample                    
      );
+    pp->bChromaFormat           = v->chromaformat;
+    ctx->report_id++;
+    if (ctx->report_id >= (1 << 16))
+        ctx->report_id = 1;
+    pp->bPicScanFixed           = ctx->report_id >> 8;
+    pp->bPicScanMethod          = ctx->report_id & 0xff;
+    pp->bPicReadbackRequests    = 0;
+    pp->bRcontrol               = v->rnd;
+    pp->bPicSpatialResid8       = (v->panscanflag  << 7) |
+                                  (v->refdist_flag << 6) |
+                                  (s->loop_filter  << 5) |
+                                  (v->fastuvmc     << 4) |
+                                  (v->extended_mv  << 3) |
+                                  (v->dquant       << 1) |
+                                  (v->vstransform      );
+    pp->bPicOverflowBlocks      = (v->quantizer_mode << 6) |
+                                  (v->multires       << 5) |
+                                  (v->resync_marker  << 4) |
+                                  (v->rangered       << 3) |
+                                  (s->max_b_frames       );
+    pp->bPicExtrapolation       = (!v->interlace || v->fcm == PROGRESSIVE) ? 1 
: 2;
+    pp->bPicDeblocked           = ((!pp->bPicBackwardPrediction && v->overlap) 
       << 6) |
+                                  ((v->profile != PROFILE_ADVANCED && 
v->rangeredfrm) << 5) |
+                                  (s->loop_filter                              
       << 1);
+    pp->bPicDeblockConfined     = (v->postprocflag             << 7) |
+                                  (v->broadcast                << 6) |
+                                  (v->interlace                << 5) |
+                                  (v->tfcntrflag               << 4) |
+                                  (v->finterpflag              << 3) |
+                                  ((s->pict_type != AV_PICTURE_TYPE_B) << 2) |
+                                  (v->psf                      << 1) |
+                                  (v->extended_dmv                 );
+    if (s->pict_type != AV_PICTURE_TYPE_I)
+        pp->bPic4MVallowed      = v->mv_mode == MV_PMODE_MIXED_MV ||
+                                  (v->mv_mode == MV_PMODE_INTENSITY_COMP &&
+                                   v->mv_mode2 == MV_PMODE_MIXED_MV);
+    if (v->profile == PROFILE_ADVANCED)
+        pp->bPicOBMC            = (v->range_mapy_flag  << 7) |
+                                  (v->range_mapy       << 4) |
+                                  (v->range_mapuv_flag << 3) |
+                                  (v->range_mapuv          );
+    pp->bPicBinPB               = 0;
+    pp->bMV_RPS                 = 0;
+    pp->bReservedBits           = 0;
+    if (s->picture_structure == PICT_FRAME) {
+        pp->wBitstreamFcodes        = v->lumscale;
+        pp->wBitstreamPCEelements   = v->lumshift;
+    } else {
+        /* Syntax: (top_field_param << 8) | bottom_field_param */
+        pp->wBitstreamFcodes        = (v->lumscale << 8) | v->lumscale;
+        pp->wBitstreamPCEelements   = (v->lumshift << 8) | v->lumshift;
+    }
+    pp->bBitstreamConcealmentNeed   = 0;
+    pp->bBitstreamConcealmentMethod = 0;
+}
+
+static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice,
+                       unsigned position, unsigned size)
+{
+    const VC1Context *v = avctx->priv_data;
+    const MpegEncContext *s = &v->s;
+
+    memset(slice, 0, sizeof(*slice));
+    slice->wHorizontalPosition = 0;
+    slice->wVerticalPosition   = s->mb_y;
+    slice->dwSliceBitsInBuffer = 8 * size;
+    slice->dwSliceDataLocation = position;
+    slice->bStartCodeBitOffset = 0;
+    slice->bReservedBits       = 0;
+    slice->wMBbitOffset        = get_bits_count(&s->gb);
+    slice->wNumberMBsInSlice   = s->mb_width * s->mb_height; /* XXX We assume 
1 slice */
+    slice->wQuantizerScaleCode = v->pq;
+    slice->wBadSliceChopping   = 0;
+}
+
+static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
+                                             DXVA2_DecodeBufferDesc *bs,
+                                             DXVA2_DecodeBufferDesc *sc)
+{
+    const VC1Context *v = avctx->priv_data;
+    struct dxva_context *ctx = avctx->hwaccel_context;
+    const MpegEncContext *s = &v->s;
+    struct dxva2_picture_context *ctx_pic = 
s->current_picture_ptr->hwaccel_picture_private;
+
+    DXVA_SliceInfo *slice = &ctx_pic->si;
+
+    static const uint8_t start_code[] = { 0, 0, 1, 0x0d };
+    const unsigned start_code_size = avctx->codec_id == AV_CODEC_ID_VC1 ? 
sizeof(start_code) : 0;
+    const unsigned slice_size = slice->dwSliceBitsInBuffer / 8;
+    const unsigned padding = 128 - ((start_code_size + slice_size) & 127);
+    const unsigned data_size = start_code_size + slice_size + padding;
+
+    void     *dxva_data_ptr;
+    uint8_t  *dxva_data;
+    unsigned dxva_size;
+    int result;
+
+    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
+                                              DXVA2_BitStreamDateBufferType,
+                                              &dxva_data_ptr, &dxva_size)))
+        return -1;
+
+    dxva_data = dxva_data_ptr;
+    result = data_size <= dxva_size ? 0 : -1;
+    if (!result) {
+        if (start_code_size > 0)
+            memcpy(dxva_data, start_code, start_code_size);
+        memcpy(dxva_data + start_code_size,
+               ctx_pic->bitstream + slice->dwSliceDataLocation, slice_size);
+        if (padding > 0)
+            memset(dxva_data + start_code_size + slice_size, 0, padding);
+        slice->dwSliceBitsInBuffer = 8 * data_size;
+    }
+    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
+                                                  
DXVA2_BitStreamDateBufferType)))
+        return -1;
+    if (result)
+        return result;
+
+    memset(bs, 0, sizeof(*bs));
+    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
+    bs->DataSize             = data_size;
+    bs->NumMBsInBuffer       = s->mb_width * s->mb_height;
+    assert((bs->DataSize & 127) == 0);
+
+    return ff_dxva2_commit_buffer(avctx, ctx, sc,
+                                  DXVA2_SliceControlBufferType,
+                                  slice, sizeof(*slice), bs->NumMBsInBuffer);
+}
+
+static int dxva2_vc1_start_frame(AVCodecContext *avctx,
+                                 av_unused const uint8_t *buffer,
+                                 av_unused uint32_t size)
+{
+    const VC1Context *v = avctx->priv_data;
+    struct dxva_context *ctx = avctx->hwaccel_context;
+    struct dxva2_picture_context *ctx_pic = 
v->s.current_picture_ptr->hwaccel_picture_private;
+
+    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
+        return -1;
+    assert(ctx_pic);
+
+    fill_picture_parameters(avctx, ctx, v, &ctx_pic->pp);
+
+    ctx_pic->bitstream_size = 0;
+    ctx_pic->bitstream      = NULL;
+    return 0;
+}
+
+static int dxva2_vc1_decode_slice(AVCodecContext *avctx,
+                                  const uint8_t *buffer,
+                                  uint32_t size)
+{
+    const VC1Context *v = avctx->priv_data;
+    const Picture *current_picture = v->s.current_picture_ptr;
+    struct dxva2_picture_context *ctx_pic = 
current_picture->hwaccel_picture_private;
+
+    if (ctx_pic->bitstream_size > 0)
+        return -1;
+
+    if (avctx->codec_id == AV_CODEC_ID_VC1 &&
+        size >= 4 && IS_MARKER(AV_RB32(buffer))) {
+        buffer += 4;
+        size   -= 4;
+    }
+
+    ctx_pic->bitstream_size = size;
+    ctx_pic->bitstream      = buffer;
+
+    fill_slice(avctx, &ctx_pic->si, 0, size);
+    return 0;
+}
+
+static int dxva2_vc1_end_frame(AVCodecContext *avctx)
+{
+    VC1Context *v = avctx->priv_data;
+    struct dxva2_picture_context *ctx_pic = 
v->s.current_picture_ptr->hwaccel_picture_private;
+    int ret;
+
+    if (ctx_pic->bitstream_size <= 0)
+        return -1;
+
+    ret = ff_dxva2_common_end_frame(avctx, v->s.current_picture_ptr->f,
+                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
+                                    NULL, 0,
+                                    commit_bitstream_and_slice_buffer);
+    if (!ret)
+        ff_mpeg_draw_horiz_band(&v->s, 0, avctx->height);
+    return ret;
+}
+
+#if CONFIG_WMV3_DXVA2_HWACCEL
+AVHWAccel ff_wmv3_dxva2_hwaccel = {
+    .name           = "wmv3_dxva2",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_WMV3,
+    .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
+    .start_frame    = dxva2_vc1_start_frame,
+    .decode_slice   = dxva2_vc1_decode_slice,
+    .end_frame      = dxva2_vc1_end_frame,
+    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
+};
+#endif
+
+AVHWAccel ff_vc1_dxva2_hwaccel = {
+    .name           = "vc1_dxva2",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_VC1,
+    .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
+    .start_frame    = dxva2_vc1_start_frame,
+    .decode_slice   = dxva2_vc1_decode_slice,
+    .end_frame      = dxva2_vc1_end_frame,
+    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
+};
-- 
2.4.0

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to