Revision 92c6a099

View differences:

configure
107 107
  --disable-rdft           disable RDFT code
108 108
  --disable-vaapi          disable VAAPI code
109 109
  --disable-vdpau          disable VDPAU code
110
  --disable-dxva2          disable DXVA2 code
110 111
  --enable-runtime-cpudetect detect cpu capabilities at runtime (bigger binary)
111 112
  --enable-hardcoded-tables use hardcoded tables instead of runtime generation
112 113
  --enable-memalign-hack   emulate memalign, interferes with memory debuggers
......
865 866
    bzlib
866 867
    dct
867 868
    doc
869
    dxva2
868 870
    fastdiv
869 871
    ffmpeg
870 872
    ffplay
......
1174 1176
h263i_decoder_select="h263_decoder"
1175 1177
h263p_encoder_select="h263_encoder"
1176 1178
h264_decoder_select="golomb"
1179
h264_dxva2_hwaccel_deps="dxva2api_h"
1180
h264_dxva2_hwaccel_select="dxva2 h264_decoder"
1177 1181
h264_vaapi_hwaccel_deps="va_va_h"
1178 1182
h264_vaapi_hwaccel_select="vaapi"
1179 1183
h264_vdpau_decoder_deps="vdpau_vdpau_h vdpau_vdpau_x11_h"
......
2399 2403

  
2400 2404
check_header conio.h
2401 2405
check_header dlfcn.h
2406
check_header dxva2api.h
2402 2407
check_header malloc.h
2403 2408
check_header poll.h
2404 2409
check_header sys/mman.h
libavcodec/Makefile
3 3
NAME = avcodec
4 4
FFLIBS = avutil
5 5

  
6
HEADERS = avcodec.h opt.h vaapi.h vdpau.h xvmc.h
6
HEADERS = avcodec.h dxva2.h opt.h vaapi.h vdpau.h xvmc.h
7 7

  
8 8
OBJS = allcodecs.o                                                      \
9 9
       audioconvert.o                                                   \
......
135 135
OBJS-$(CONFIG_H264_DECODER)            += h264.o h264idct.o h264pred.o h264_loopfilter.o h264_direct.o cabac.o \
136 136
                                          h264_sei.o h264_ps.o h264_refs.o h264_cavlc.o h264_cabac.o\
137 137
                                          mpegvideo.o error_resilience.o
138
OBJS-$(CONFIG_H264_DXVA2_HWACCEL)      += dxva2_h264.o
138 139
OBJS-$(CONFIG_H264_ENCODER)            += h264enc.o h264dspenc.o
139 140
OBJS-$(CONFIG_H264_VAAPI_HWACCEL)      += vaapi_h264.o
140 141
OBJS-$(CONFIG_HUFFYUV_DECODER)         += huffyuv.o
libavcodec/allcodecs.c
55 55

  
56 56
    /* hardware accelerators */
57 57
    REGISTER_HWACCEL (H263_VAAPI, h263_vaapi);
58
    REGISTER_HWACCEL (H264_DXVA2, h264_dxva2);
58 59
    REGISTER_HWACCEL (H264_VAAPI, h264_vaapi);
59 60
    REGISTER_HWACCEL (MPEG2_VAAPI, mpeg2_vaapi);
60 61
    REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi);
libavcodec/dxva2.h
1
/*
2
 * DXVA2 HW acceleration
3
 *
4
 * copyright (c) 2009 Laurent Aimar
5
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with FFmpeg; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22

  
23
#ifndef AVCODEC_DXVA_H
24
#define AVCODEC_DXVA_H
25

  
26
#include <stdint.h>
27

  
28
#include <dxva2api.h>
29

  
30
/**
31
 * This structure is used to provides the necessary configurations and data
32
 * to the DXVA2 FFmpeg HWAccel implementation.
33
 *
34
 * The application must make it available as AVCodecContext.hwaccel_context.
35
 */
36
struct dxva_context {
37
    /**
38
     * DXVA2 decoder object
39
     */
40
    IDirectXVideoDecoder *decoder;
41

  
42
    /**
43
     * DXVA2 configuration used to create the decoder
44
     */
45
    const DXVA2_ConfigPictureDecode *cfg;
46

  
47
    /**
48
     * The number of surface in the surface array
49
     */
50
    unsigned surface_count;
51

  
52
    /**
53
     * The array of Direct3D surfaces used to create the decoder
54
     */
55
    LPDIRECT3DSURFACE9 *surface;
56

  
57
    /**
58
     * A bit field configuring the workarounds needed for using the decoder
59
     */
60
    uint64_t workaround;
61

  
62
    /**
63
     * Private to the FFmpeg AVHWAccel implementation
64
     */
65
    unsigned report_id;
66
};
67

  
68
#endif /* AVCODEC_DXVA_H */
libavcodec/dxva2_h264.c
1
/*
2
 * DXVA2 H264 HW acceleration.
3
 *
4
 * copyright (c) 2009 Laurent Aimar
5
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with FFmpeg; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22

  
23
#include "dxva2.h"
24
#include "avcodec.h"
25

  
26
#include "mpegvideo.h"
27
#include "h264.h"
28
#include "h264data.h"
29

  
30
struct dxva2_picture_context {
31
    DXVA_PicParams_H264   pp;
32
    DXVA_Qmatrix_H264     qm;
33
    unsigned              slice_count;
34
    DXVA_Slice_H264_Short slice_short[MAX_SLICES];
35
    DXVA_Slice_H264_Long  slice_long[MAX_SLICES];
36
    const uint8_t         *bitstream;
37
    unsigned              bitstream_size;
38
};
39

  
40
static void *get_surface(const Picture *picture)
41
{
42
    return picture->data[3];
43
}
44
static unsigned get_surface_index(const struct dxva_context *ctx,
45
                                  const Picture *picture)
46
{
47
    void *surface = get_surface(picture);
48
    unsigned i;
49

  
50
    for (i = 0; i < ctx->surface_count; i++)
51
        if (ctx->surface[i] == surface)
52
            return i;
53

  
54
    assert(0);
55
    return 0;
56
}
57

  
58
static void fill_picture_entry(DXVA_PicEntry_H264 *pic,
59
                               unsigned index, unsigned flag)
60
{
61
    assert((index&0x7f) == index && (flag&0x01) == flag);
62
    pic->bPicEntry = index | (flag << 7);
63
}
64

  
65
static void fill_picture_parameters(struct dxva_context *ctx, const H264Context *h,
66
                                    DXVA_PicParams_H264 *pp)
67
{
68
    const MpegEncContext *s = &h->s;
69
    const Picture *current_picture = s->current_picture_ptr;
70
    int i;
71

  
72
    memset(pp, 0, sizeof(*pp));
73
    /* Configure current picture */
74
    fill_picture_entry(&pp->CurrPic,
75
                       get_surface_index(ctx, current_picture),
76
                       s->picture_structure == PICT_BOTTOM_FIELD);
77
    /* Configure the set of references */
78
    pp->UsedForReferenceFlags  = 0;
79
    pp->NonExistingFrameFlags  = 0;
80
    for (i = 0; i < FF_ARRAY_ELEMS(pp->RefFrameList); i++) {
81
        if (i < h->short_ref_count + h->long_ref_count) {
82
            const Picture *r;
83
            if (i < h->short_ref_count) {
84
                r = h->short_ref[i];
85
                assert(!r->long_ref);
86
            } else {
87
                r = h->long_ref[i - h->short_ref_count];
88
                assert(r->long_ref);
89
            }
90
            fill_picture_entry(&pp->RefFrameList[i],
91
                               get_surface_index(ctx, r),
92
                               r->long_ref != 0);
93

  
94
            if ((r->reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX)
95
                pp->FieldOrderCntList[i][0] = r->field_poc[0];
96
            if ((r->reference & PICT_BOTTOM_FIELD) && r->field_poc[1] != INT_MAX)
97
                pp->FieldOrderCntList[i][1] = r->field_poc[1];
98

  
99
            pp->FrameNumList[i] = r->long_ref ? r->pic_id : r->frame_num;
100
            if (r->reference & PICT_TOP_FIELD)
101
                pp->UsedForReferenceFlags |= 1 << (2*i + 0);
102
            if (r->reference & PICT_BOTTOM_FIELD)
103
                pp->UsedForReferenceFlags |= 1 << (2*i + 1);
104
        } else {
105
            pp->RefFrameList[i].bPicEntry = 0xff;
106
            pp->FieldOrderCntList[i][0]   = 0;
107
            pp->FieldOrderCntList[i][1]   = 0;
108
            pp->FrameNumList[i]           = 0;
109
        }
110
    }
111

  
112
    pp->wFrameWidthInMbsMinus1        = s->mb_width  - 1;
113
    pp->wFrameHeightInMbsMinus1       = s->mb_height - 1;
114
    pp->num_ref_frames                = h->sps.ref_frame_count;
115

  
116
    pp->wBitFields                    = ((s->picture_structure != PICT_FRAME) <<  0) |
117
                                        (h->sps.mb_aff                        <<  1) |
118
                                        (h->sps.residual_color_transform_flag <<  2) |
119
                                        /* sp_for_switch_flag (not implemented by FFmpeg) */
120
                                        (0                                    <<  3) |
121
                                        (h->sps.chroma_format_idc             <<  4) |
122
                                        ((h->nal_ref_idc != 0)                <<  6) |
123
                                        (h->pps.constrained_intra_pred        <<  7) |
124
                                        (h->pps.weighted_pred                 <<  8) |
125
                                        (h->pps.weighted_bipred_idc           <<  9) |
126
                                        /* MbsConsecutiveFlag */
127
                                        (1                                    << 11) |
128
                                        (h->sps.frame_mbs_only_flag           << 12) |
129
                                        (h->pps.transform_8x8_mode            << 13) |
130
                                        ((h->sps.level_idc >= 31)             << 14) |
131
                                        /* IntraPicFlag (Modified if we detect a non
132
                                         * intra slice in decode_slice) */
133
                                        (1                                    << 15);
134

  
135
    pp->bit_depth_luma_minus8         = h->sps.bit_depth_luma - 8;
136
    pp->bit_depth_chroma_minus8       = h->sps.bit_depth_chroma - 8;
137
    pp->Reserved16Bits                = 3; /* FIXME is there a way to detect the right mode ? */
138
    pp->StatusReportFeedbackNumber    = 1 + ctx->report_id++;
139
    pp->CurrFieldOrderCnt[0] = 0;
140
    if ((s->picture_structure & PICT_TOP_FIELD) &&
141
        current_picture->field_poc[0] != INT_MAX)
142
        pp->CurrFieldOrderCnt[0] = current_picture->field_poc[0];
143
    pp->CurrFieldOrderCnt[1] = 0;
144
    if ((s->picture_structure & PICT_BOTTOM_FIELD) &&
145
        current_picture->field_poc[1] != INT_MAX)
146
        pp->CurrFieldOrderCnt[1] = current_picture->field_poc[1];
147
    pp->pic_init_qs_minus26           = h->pps.init_qs - 26;
148
    pp->chroma_qp_index_offset        = h->pps.chroma_qp_index_offset[0];
149
    pp->second_chroma_qp_index_offset = h->pps.chroma_qp_index_offset[1];
150
    pp->ContinuationFlag              = 1;
151
    pp->pic_init_qp_minus26           = h->pps.init_qp - 26;
152
    pp->num_ref_idx_l0_active_minus1  = h->pps.ref_count[0] - 1;
153
    pp->num_ref_idx_l1_active_minus1  = h->pps.ref_count[1] - 1;
154
    pp->Reserved8BitsA                = 0;
155
    pp->frame_num                     = h->frame_num;
156
    pp->log2_max_frame_num_minus4     = h->sps.log2_max_frame_num - 4;
157
    pp->pic_order_cnt_type            = h->sps.poc_type;
158
    if (h->sps.poc_type == 0)
159
        pp->log2_max_pic_order_cnt_lsb_minus4 = h->sps.log2_max_poc_lsb - 4;
160
    else if (h->sps.poc_type == 1)
161
        pp->delta_pic_order_always_zero_flag = h->sps.delta_pic_order_always_zero_flag;
162
    pp->direct_8x8_inference_flag     = h->sps.direct_8x8_inference_flag;
163
    pp->entropy_coding_mode_flag      = h->pps.cabac;
164
    pp->pic_order_present_flag        = h->pps.pic_order_present;
165
    pp->num_slice_groups_minus1       = h->pps.slice_group_count - 1;
166
    pp->slice_group_map_type          = h->pps.mb_slice_group_map_type;
167
    pp->deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present;
168
    pp->redundant_pic_cnt_present_flag= h->pps.redundant_pic_cnt_present;
169
    pp->Reserved8BitsB                = 0;
170
    pp->slice_group_change_rate_minus1= 0;  /* XXX not implemented by FFmpeg */
171
    //pp->SliceGroupMap[810];               /* XXX not implemented by FFmpeg */
172
}
173

  
174
static void fill_scaling_lists(const H264Context *h, DXVA_Qmatrix_H264 *qm)
175
{
176
    unsigned i, j;
177
    memset(qm, 0, sizeof(*qm));
178
    for (i = 0; i < 6; i++)
179
        for (j = 0; j < 16; j++)
180
            qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][zigzag_scan[j]];
181

  
182
    for (i = 0; i < 2; i++)
183
        for (j = 0; j < 64; j++)
184
            qm->bScalingLists8x8[i][j] = h->pps.scaling_matrix8[i][ff_zigzag_direct[j]];
185
}
186

  
187
static int is_slice_short(struct dxva_context *ctx)
188
{
189
    assert(ctx->cfg->ConfigBitstreamRaw == 1 ||
190
           ctx->cfg->ConfigBitstreamRaw == 2);
191
    return ctx->cfg->ConfigBitstreamRaw == 2;
192
}
193

  
194
static void fill_slice_short(DXVA_Slice_H264_Short *slice,
195
                             unsigned position, unsigned size)
196
{
197
    memset(slice, 0, sizeof(*slice));
198
    slice->BSNALunitDataLocation = position;
199
    slice->SliceBytesInBuffer    = size;
200
    slice->wBadSliceChopping     = 0;
201
}
202

  
203
static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
204
                            unsigned position, unsigned size)
205
{
206
    H264Context *h = avctx->priv_data; /* FIXME Can't use const because of get_bits_count */
207
    struct dxva_context *ctx = avctx->hwaccel_context;
208
    MpegEncContext *s = &h->s;
209
    unsigned list;
210

  
211
    memset(slice, 0, sizeof(*slice));
212
    slice->BSNALunitDataLocation = position;
213
    slice->SliceBytesInBuffer    = size;
214
    slice->wBadSliceChopping     = 0;
215

  
216
    slice->first_mb_in_slice     = (s->mb_y >> FIELD_OR_MBAFF_PICTURE) * s->mb_width + s->mb_x;
217
    slice->NumMbsForSlice        = 0; /* XXX it is set once we have all slices */
218
    slice->BitOffsetToSliceData  = get_bits_count(&s->gb) + 8;
219
    slice->slice_type            = ff_h264_get_slice_type(h);
220
    if (h->slice_type_fixed)
221
        slice->slice_type += 5;
222
    slice->luma_log2_weight_denom       = h->luma_log2_weight_denom;
223
    slice->chroma_log2_weight_denom     = h->chroma_log2_weight_denom;
224
    if (h->list_count > 0)
225
        slice->num_ref_idx_l0_active_minus1 = h->ref_count[0] - 1;
226
    if (h->list_count > 1)
227
        slice->num_ref_idx_l1_active_minus1 = h->ref_count[1] - 1;
228
    slice->slice_alpha_c0_offset_div2   = h->slice_alpha_c0_offset / 2;
229
    slice->slice_beta_offset_div2       = h->slice_beta_offset / 2;
230
    slice->Reserved8Bits                = 0;
231

  
232
    for (list = 0; list < 2; list++) {
233
        unsigned i;
234
        for (i = 0; i < FF_ARRAY_ELEMS(slice->RefPicList[list]); i++) {
235
            if (list < h->list_count && i < h->ref_count[list]) {
236
                const Picture *r = &h->ref_list[list][i];
237
                unsigned plane;
238
                fill_picture_entry(&slice->RefPicList[list][i],
239
                                   get_surface_index(ctx, r),
240
                                   r->reference == PICT_BOTTOM_FIELD);
241
                for (plane = 0; plane < 3; plane++) {
242
                    int w, o;
243
                    if (plane == 0 && h->luma_weight_flag[list]) {
244
                        w = h->luma_weight[list][i];
245
                        o = h->luma_offset[list][i];
246
                    } else if (plane >= 1 && h->chroma_weight_flag[list]) {
247
                        w = h->chroma_weight[list][i][plane-1];
248
                        o = h->chroma_offset[list][i][plane-1];
249
                    } else {
250
                        w = 1 << (plane == 0 ? h->luma_log2_weight_denom :
251
                                               h->chroma_log2_weight_denom);
252
                        o = 0;
253
                    }
254
                    slice->Weights[list][i][plane][0] = w;
255
                    slice->Weights[list][i][plane][1] = o;
256
                }
257
            } else {
258
                unsigned plane;
259
                slice->RefPicList[list][i].bPicEntry = 0xff;
260
                for (plane = 0; plane < 3; plane++) {
261
                    slice->Weights[list][i][plane][0] = 0;
262
                    slice->Weights[list][i][plane][1] = 0;
263
                }
264
            }
265
        }
266
    }
267
    slice->slice_qs_delta    = 0; /* XXX not implemented by FFmpeg */
268
    slice->slice_qp_delta    = s->qscale - h->pps.init_qp;
269
    slice->redundant_pic_cnt = h->redundant_pic_count;
270
    if (h->slice_type == FF_B_TYPE)
271
        slice->direct_spatial_mv_pred_flag = h->direct_spatial_mv_pred;
272
    slice->cabac_init_idc = h->pps.cabac ? h->cabac_init_idc : 0;
273
    if (h->deblocking_filter < 2)
274
        slice->disable_deblocking_filter_idc = 1 - h->deblocking_filter;
275
    else
276
        slice->disable_deblocking_filter_idc = h->deblocking_filter;
277
    slice->slice_id = h->current_slice - 1;
278
}
279

  
280
static int commit_buffer(AVCodecContext *avctx,
281
                         struct dxva_context *ctx,
282
                         DXVA2_DecodeBufferDesc *dsc,
283
                         unsigned type, const void *data, unsigned size,
284
                         unsigned mb_count)
285
{
286
    void     *dxva_data;
287
    unsigned dxva_size;
288
    int      result;
289

  
290
    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, type,
291
                                              &dxva_data, &dxva_size))) {
292
        av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %d\n", type);
293
        return -1;
294
    }
295
    if (size <= dxva_size) {
296
        memcpy(dxva_data, data, size);
297

  
298
        memset(dsc, 0, sizeof(*dsc));
299
        dsc->CompressedBufferType = type;
300
        dsc->DataSize             = size;
301
        dsc->NumMBsInBuffer       = mb_count;
302

  
303
        result = 0;
304
    } else {
305
        av_log(avctx, AV_LOG_ERROR, "Buffer for type %d was too small\n", type);
306
        result = -1;
307
    }
308
    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, type))) {
309
        av_log(avctx, AV_LOG_ERROR, "Failed to release buffer type %d\n", type);
310
        result = -1;
311
    }
312
    return result;
313
}
314

  
315
static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
316
                                             struct dxva_context *ctx,
317
                                             struct dxva2_picture_context *ctx_pic,
318
                                             DXVA2_DecodeBufferDesc *bs,
319
                                             DXVA2_DecodeBufferDesc *sc,
320
                                             unsigned mb_count)
321
{
322
    DXVA_Slice_H264_Short *slice = NULL;
323
    uint8_t  *dxva_data, *current, *end;
324
    unsigned dxva_size;
325
    void     *slice_data;
326
    unsigned slice_size;
327
    unsigned padding;
328
    unsigned i;
329

  
330
    /* Create an annex B bitstream buffer with only slice NAL and finalize slice */
331
    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
332
                                               DXVA2_BitStreamDateBufferType,
333
                                               &dxva_data, &dxva_size)))
334
        return -1;
335
    current = dxva_data;
336
    end = dxva_data + dxva_size;
337

  
338
    for (i = 0; i < ctx_pic->slice_count; i++) {
339
        static const uint8_t start_code[] = { 0, 0, 1 };
340
        static const unsigned start_code_size = sizeof(start_code);
341
        unsigned position, size;
342

  
343
        assert(offsetof(DXVA_Slice_H264_Short, BSNALunitDataLocation) ==
344
               offsetof(DXVA_Slice_H264_Long,  BSNALunitDataLocation));
345
        assert(offsetof(DXVA_Slice_H264_Short, SliceBytesInBuffer) ==
346
               offsetof(DXVA_Slice_H264_Long,  SliceBytesInBuffer));
347

  
348
        if (is_slice_short(ctx))
349
            slice = &ctx_pic->slice_short[i];
350
        else
351
            slice = (DXVA_Slice_H264_Short*)&ctx_pic->slice_long[i];
352

  
353
        position = slice->BSNALunitDataLocation;
354
        size     = slice->SliceBytesInBuffer;
355
        if (start_code_size + size > end - current) {
356
            av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream");
357
            break;
358
        }
359

  
360
        slice->BSNALunitDataLocation = current - dxva_data;
361
        slice->SliceBytesInBuffer    = start_code_size + size;
362

  
363
        if (!is_slice_short(ctx)) {
364
            DXVA_Slice_H264_Long *slice_long = (DXVA_Slice_H264_Long*)slice;
365
            if (i < ctx_pic->slice_count - 1)
366
                slice_long->NumMbsForSlice =
367
                    slice_long[1].first_mb_in_slice - slice_long[0].first_mb_in_slice;
368
            else
369
                slice_long->NumMbsForSlice = mb_count - slice_long->first_mb_in_slice;
370
        }
371

  
372
        memcpy(current, start_code, start_code_size);
373
        current += start_code_size;
374

  
375
        memcpy(current, &ctx_pic->bitstream[position], size);
376
        current += size;
377
    }
378
    padding = FFMIN(128 - ((current - dxva_data) & 127), end - current);
379
    if (slice && padding > 0) {
380
        memset(current, 0, padding);
381
        current += padding;
382

  
383
        slice->SliceBytesInBuffer += padding;
384
    }
385
    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
386
                                                  DXVA2_BitStreamDateBufferType)))
387
        return -1;
388
    if (i < ctx_pic->slice_count)
389
        return -1;
390

  
391
    memset(bs, 0, sizeof(*bs));
392
    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
393
    bs->DataSize             = current - dxva_data;
394
    bs->NumMBsInBuffer       = mb_count;
395

  
396
    if (is_slice_short(ctx)) {
397
        slice_data = ctx_pic->slice_short;
398
        slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short);
399
    } else {
400
        slice_data = ctx_pic->slice_long;
401
        slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_long);
402
    }
403
    assert((bs->DataSize & 127) == 0);
404
    return commit_buffer(avctx, ctx, sc,
405
                         DXVA2_SliceControlBufferType,
406
                         slice_data, slice_size, mb_count);
407
}
408

  
409

  
410
static int start_frame(AVCodecContext *avctx,
411
                       av_unused const uint8_t *buffer,
412
                       av_unused uint32_t size)
413
{
414
    const H264Context *h = avctx->priv_data;
415
    struct dxva_context *ctx = avctx->hwaccel_context;
416
    struct dxva2_picture_context *ctx_pic = h->s.current_picture_ptr->hwaccel_picture_private;
417

  
418
    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
419
        return -1;
420
    assert(ctx_pic);
421

  
422
    /* Fill up DXVA_PicParams_H264 */
423
    fill_picture_parameters(ctx, h, &ctx_pic->pp);
424

  
425
    /* Fill up DXVA_Qmatrix_H264 */
426
    fill_scaling_lists(h, &ctx_pic->qm);
427

  
428
    ctx_pic->slice_count    = 0;
429
    ctx_pic->bitstream_size = 0;
430
    ctx_pic->bitstream      = NULL;
431
    return 0;
432
}
433

  
434
static int decode_slice(AVCodecContext *avctx,
435
                        const uint8_t *buffer, uint32_t size)
436
{
437
    H264Context *h = avctx->priv_data; /* FIXME Can't use const because of get_bits_count */
438
    struct dxva_context *ctx = avctx->hwaccel_context;
439
    const Picture *current_picture = h->s.current_picture_ptr;
440
    struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
441
    unsigned position;
442

  
443
    if (ctx_pic->slice_count >= MAX_SLICES)
444
        return -1;
445

  
446
    if (!ctx_pic->bitstream)
447
        ctx_pic->bitstream = buffer;
448
    ctx_pic->bitstream_size += size;
449

  
450
    position = buffer - ctx_pic->bitstream;
451
    if (is_slice_short(ctx))
452
        fill_slice_short(&ctx_pic->slice_short[ctx_pic->slice_count],
453
                         position, size);
454
    else
455
        fill_slice_long(avctx, &ctx_pic->slice_long[ctx_pic->slice_count],
456
                        position, size);
457
    ctx_pic->slice_count++;
458

  
459
    if (h->slice_type != FF_I_TYPE && h->slice_type != FF_SI_TYPE)
460
        ctx_pic->pp.wBitFields &= ~(1 << 15); /* Set IntraPicFlag to 0 */
461
    return 0;
462
}
463

  
464
static int end_frame(AVCodecContext *avctx)
465
{
466
    H264Context *h = avctx->priv_data;
467
    MpegEncContext *s = &h->s;
468
    const unsigned mb_count = s->mb_width * s->mb_height;
469
    struct dxva_context *ctx = avctx->hwaccel_context;
470
    const Picture *current_picture = h->s.current_picture_ptr;
471
    struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
472
    unsigned               buffer_count = 0;
473
    DXVA2_DecodeBufferDesc buffer[4];
474
    DXVA2_DecodeExecuteParams exec;
475
    int      result;
476

  
477
    if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
478
        return -1;
479

  
480
    if (FAILED(IDirectXVideoDecoder_BeginFrame(ctx->decoder,
481
                                               get_surface(current_picture),
482
                                               NULL))) {
483
        av_log(avctx, AV_LOG_ERROR, "Failed to begin frame\n");
484
        return -1;
485
    }
486

  
487
    result = commit_buffer(avctx, ctx, &buffer[buffer_count],
488
                           DXVA2_PictureParametersBufferType,
489
                           &ctx_pic->pp, sizeof(ctx_pic->pp), 0);
490
    if (result) {
491
        av_log(avctx, AV_LOG_ERROR,
492
               "Failed to add picture parameter buffer\n");
493
        goto end;
494
    }
495
    buffer_count++;
496

  
497
    result = commit_buffer(avctx, ctx, &buffer[buffer_count],
498
                           DXVA2_InverseQuantizationMatrixBufferType,
499
                           &ctx_pic->qm, sizeof(ctx_pic->qm), 0);
500
    if (result) {
501
        av_log(avctx, AV_LOG_ERROR,
502
               "Failed to add inverse quantization matrix buffer\n");
503
        goto end;
504
    }
505
    buffer_count++;
506

  
507
    result = commit_bitstream_and_slice_buffer(avctx, ctx, ctx_pic,
508
                                               &buffer[buffer_count + 0],
509
                                               &buffer[buffer_count + 1],
510
                                               mb_count);
511
    if (result) {
512
        av_log(avctx, AV_LOG_ERROR,
513
               "Failed to add bitstream or slice control buffer\n");
514
        goto end;
515
    }
516
    buffer_count += 2;
517

  
518
    /* TODO Film Grain when possible */
519

  
520
    assert(buffer_count == 4);
521

  
522
    memset(&exec, 0, sizeof(exec));
523
    exec.NumCompBuffers      = buffer_count;
524
    exec.pCompressedBuffers  = buffer;
525
    exec.pExtensionData      = NULL;
526
    if (FAILED(IDirectXVideoDecoder_Execute(ctx->decoder, &exec))) {
527
        av_log(avctx, AV_LOG_ERROR, "Failed to execute\n");
528
        result = -1;
529
    }
530

  
531
end:
532
    if (FAILED(IDirectXVideoDecoder_EndFrame(ctx->decoder, NULL))) {
533
        av_log(avctx, AV_LOG_ERROR, "Failed to end frame\n");
534
        result = -1;
535
    }
536

  
537
    if (!result)
538
        ff_draw_horiz_band(s, 0, s->avctx->height);
539
    return result;
540
}
541

  
542
AVHWAccel h264_dxva2_hwaccel = {
543
    .name           = "h264_dxva2",
544
    .type           = CODEC_TYPE_VIDEO,
545
    .id             = CODEC_ID_H264,
546
    .pix_fmt        = PIX_FMT_DXVA2_VLD,
547
    .capabilities   = 0,
548
    .start_frame    = start_frame,
549
    .decode_slice   = decode_slice,
550
    .end_frame      = end_frame,
551
    .priv_data_size = sizeof(struct dxva2_picture_context),
552
};
553

  
libavcodec/mpegvideo.c
81 81
};
82 82

  
83 83
const enum PixelFormat ff_hwaccel_pixfmt_list_420[] = {
84
    PIX_FMT_DXVA2_VLD,
84 85
    PIX_FMT_VAAPI_VLD,
85 86
    PIX_FMT_YUV420P,
86 87
    PIX_FMT_NONE
libavutil/pixdesc.c
646 646
        },
647 647
        .flags = PIX_FMT_BE,
648 648
    },
649
    [PIX_FMT_DXVA2_VLD] = {
650
        .name = "dxva2_vld",
651
        .log2_chroma_w = 1,
652
        .log2_chroma_h = 1,
653
        .flags = PIX_FMT_HWACCEL,
654
    },
649 655
};
650 656

  
651 657
int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
libavutil/pixfmt.h
126 126
    PIX_FMT_YUV444P16LE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
127 127
    PIX_FMT_YUV444P16BE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
128 128
    PIX_FMT_VDPAU_MPEG4,  ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
129
    PIX_FMT_DXVA2_VLD,    ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer
129 130
    PIX_FMT_NB,        ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
130 131
};
131 132

  

Also available in: Unified diff