1 /*
2 * DXVA2 H.264 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
24
30
32 DXVA_PicParams_H264
pp;
39 };
40
43 {
44 assert((index&0x7f) == index && (flag&0x01) == flag);
45 pic->bPicEntry = index | (flag << 7);
46 }
47
49 DXVA_PicParams_H264 *pp)
50 {
54 int i, j;
55
56 memset(pp, 0, sizeof(*pp));
57 /* Configure current picture */
61 /* Configure the set of references */
62 pp->UsedForReferenceFlags = 0;
63 pp->NonExistingFrameFlags = 0;
66 if (j < h->short_ref_count) {
68 } else {
70 while (!r && j < h->short_ref_count + 16)
72 }
73 if (r) {
77
79 pp->FieldOrderCntList[i][0] = r->
field_poc[0];
81 pp->FieldOrderCntList[i][1] = r->
field_poc[1];
82
85 pp->UsedForReferenceFlags |= 1 << (2*i + 0);
87 pp->UsedForReferenceFlags |= 1 << (2*i + 1);
88 } else {
89 pp->RefFrameList[i].bPicEntry = 0xff;
90 pp->FieldOrderCntList[i][0] = 0;
91 pp->FieldOrderCntList[i][1] = 0;
92 pp->FrameNumList[i] = 0;
93 }
94 }
95
96 pp->wFrameWidthInMbsMinus1 = h->
mb_width - 1;
97 pp->wFrameHeightInMbsMinus1 = h->
mb_height - 1;
99
104 /* sp_for_switch_flag (not implemented by FFmpeg) */
105 (0 << 3) |
111 /* MbsConsecutiveFlag */
112 (1 << 11) |
116 /* IntraPicFlag (Modified if we detect a non
117 * intra slice in dxva2_h264_decode_slice) */
118 (1 << 15);
119
123 pp->Reserved16Bits = 0;
125 pp->Reserved16Bits = 0x34c;
126 else
127 pp->Reserved16Bits = 3; /* FIXME is there a way to detect the right mode ? */
128 pp->StatusReportFeedbackNumber = 1 + DXVA_CONTEXT_REPORT_ID(avctx, ctx)++;
129 pp->CurrFieldOrderCnt[0] = 0;
131 current_picture->
field_poc[0] != INT_MAX)
132 pp->CurrFieldOrderCnt[0] = current_picture->
field_poc[0];
133 pp->CurrFieldOrderCnt[1] = 0;
135 current_picture->
field_poc[1] != INT_MAX)
136 pp->CurrFieldOrderCnt[1] = current_picture->
field_poc[1];
137 pp->pic_init_qs_minus26 = pps->
init_qs - 26;
140 pp->ContinuationFlag = 1;
141 pp->pic_init_qp_minus26 = pps->
init_qp - 26;
142 pp->num_ref_idx_l0_active_minus1 = pps->
ref_count[0] - 1;
143 pp->num_ref_idx_l1_active_minus1 = pps->
ref_count[1] - 1;
144 pp->Reserved8BitsA = 0;
147 pp->pic_order_cnt_type = sps->
poc_type;
153 pp->entropy_coding_mode_flag = pps->
cabac;
159 pp->Reserved8BitsB = 0;
160 pp->slice_group_change_rate_minus1= 0; /* XXX not implemented by FFmpeg */
161 //pp->SliceGroupMap[810]; /* XXX not implemented by FFmpeg */
162 }
163
165 {
167 unsigned i, j;
168 memset(qm, 0, sizeof(*qm));
170 for (i = 0; i < 6; i++)
171 for (j = 0; j < 16; j++)
173
174 for (i = 0; i < 64; i++) {
177 }
178 } else {
179 for (i = 0; i < 6; i++)
180 for (j = 0; j < 16; j++)
182
183 for (i = 0; i < 64; i++) {
186 }
187 }
188 }
189
191 {
192 assert(DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) == 1 ||
193 DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) == 2);
194 return DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) == 2;
195 }
196
198 unsigned position,
unsigned size)
199 {
200 memset(slice, 0, sizeof(*slice));
201 slice->BSNALunitDataLocation = position;
202 slice->SliceBytesInBuffer =
size;
203 slice->wBadSliceChopping = 0;
204 }
205
207 {
208 int i;
210 if ((pp->RefFrameList[i].bPicEntry & 0x7f) == surface_index)
211 return i;
212 }
213 return 0x7f;
214 }
215
217 const DXVA_PicParams_H264 *pp,
unsigned position,
unsigned size)
218 {
222 unsigned list;
223
224 memset(slice, 0, sizeof(*slice));
225 slice->BSNALunitDataLocation = position;
226 slice->SliceBytesInBuffer =
size;
227 slice->wBadSliceChopping = 0;
228
230 slice->NumMbsForSlice = 0; /* XXX it is set once we have all slices */
234 slice->slice_type += 5;
238 slice->num_ref_idx_l0_active_minus1 = sl->
ref_count[0] - 1;
240 slice->num_ref_idx_l1_active_minus1 = sl->
ref_count[1] - 1;
243 slice->Reserved8Bits = 0;
244
245 for (list = 0; list < 2; list++) {
246 unsigned i;
248 if (list < sl->list_count && i < sl->ref_count[list]) {
254 else
258 for (plane = 0; plane < 3; plane++) {
266 } else {
269 o = 0;
270 }
271 slice->Weights[list][i][
plane][0] =
w;
272 slice->Weights[list][i][
plane][1] = o;
273 }
274 } else {
276 slice->RefPicList[list][i].bPicEntry = 0xff;
277 for (plane = 0; plane < 3; plane++) {
278 slice->Weights[list][i][
plane][0] = 0;
279 slice->Weights[list][i][
plane][1] = 0;
280 }
281 }
282 }
283 }
284 slice->slice_qs_delta = 0; /* XXX not implemented by FFmpeg */
292 else
295 }
296
300 {
307 void *dxva_data_ptr =
NULL;
309 unsigned dxva_size = 0;
310 void *slice_data;
311 unsigned slice_size;
312 unsigned padding;
313 unsigned i;
315
316 /* Create an annex B bitstream buffer with only slice NAL and finalize slice */
317 #if CONFIG_D3D11VA
319 type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
322 type,
323 &dxva_size, &dxva_data_ptr)))
324 return -1;
325 }
326 #endif
327 #if CONFIG_DXVA2
329 type = DXVA2_BitStreamDateBufferType;
331 type,
332 &dxva_data_ptr, &dxva_size)))
333 return -1;
334 }
335 #endif
336
337 dxva_data = dxva_data_ptr;
338 current = dxva_data;
339 end = dxva_data + dxva_size;
340
343 static const unsigned start_code_size =
sizeof(
start_code);
344 unsigned position,
size;
345
346 assert(offsetof(DXVA_Slice_H264_Short, BSNALunitDataLocation) ==
347 offsetof(DXVA_Slice_H264_Long, BSNALunitDataLocation));
348 assert(offsetof(DXVA_Slice_H264_Short, SliceBytesInBuffer) ==
349 offsetof(DXVA_Slice_H264_Long, SliceBytesInBuffer));
350
353 else
354 slice = (DXVA_Slice_H264_Short*)&ctx_pic->
slice_long[i];
355
356 position = slice->BSNALunitDataLocation;
357 size = slice->SliceBytesInBuffer;
358 if (start_code_size + size > end - current) {
360 break;
361 }
362
363 slice->BSNALunitDataLocation = current - dxva_data;
364 slice->SliceBytesInBuffer = start_code_size +
size;
365
367 DXVA_Slice_H264_Long *
slice_long = (DXVA_Slice_H264_Long*)slice;
369 slice_long->NumMbsForSlice =
370 slice_long[1].first_mb_in_slice - slice_long[0].first_mb_in_slice;
371 else
372 slice_long->NumMbsForSlice = mb_count - slice_long->first_mb_in_slice;
373 }
374
375 memcpy(current, start_code, start_code_size);
376 current += start_code_size;
377
378 memcpy(current, &ctx_pic->
bitstream[position], size);
380 }
381 padding =
FFMIN(128 - ((current - dxva_data) & 127), end - current);
382 if (slice && padding > 0) {
383 memset(current, 0, padding);
384 current += padding;
385
386 slice->SliceBytesInBuffer += padding;
387 }
388 #if CONFIG_D3D11VA
391 return -1;
392 #endif
393 #if CONFIG_DXVA2
396 return -1;
397 #endif
399 return -1;
400
401 #if CONFIG_D3D11VA
403 D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
404 memset(dsc11, 0, sizeof(*dsc11));
405 dsc11->BufferType =
type;
406 dsc11->DataSize = current - dxva_data;
407 dsc11->NumMBsInBuffer = mb_count;
408
409 type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
410
412 }
413 #endif
414 #if CONFIG_DXVA2
416 DXVA2_DecodeBufferDesc *dsc2 = bs;
417 memset(dsc2, 0, sizeof(*dsc2));
418 dsc2->CompressedBufferType =
type;
419 dsc2->DataSize = current - dxva_data;
420 dsc2->NumMBsInBuffer = mb_count;
421
422 type = DXVA2_SliceControlBufferType;
423
425 }
426 #endif
427
431 } else {
434 }
436 type,
437 slice_data, slice_size, mb_count);
438 }
439
440
444 {
448
449 if (!DXVA_CONTEXT_VALID(avctx, ctx))
450 return -1;
451 assert(ctx_pic);
452
453 /* Fill up DXVA_PicParams_H264 */
455
456 /* Fill up DXVA_Qmatrix_H264 */
458
462 return 0;
463 }
464
468 {
474 unsigned position;
475
477 return -1;
478
482
486 position, size);
487 else
489 &ctx_pic->
pp, position, size);
491
493 ctx_pic->
pp.wBitFields &= ~(1 << 15);
/* Set IntraPicFlag to 0 */
494 return 0;
495 }
496
498 {
503 int ret;
504
506 return -1;
508 &ctx_pic->
pp,
sizeof(ctx_pic->
pp),
509 &ctx_pic->
qm,
sizeof(ctx_pic->
qm),
511 if (!ret)
513 return ret;
514 }
515
516 #if CONFIG_H264_DXVA2_HWACCEL
518 .
name =
"h264_dxva2",
530 };
531 #endif
532
533 #if CONFIG_H264_D3D11VA_HWACCEL
535 .
name =
"h264_d3d11va",
547 };
548 #endif
549
550 #if CONFIG_H264_D3D11VA2_HWACCEL
552 .
name =
"h264_d3d11va2",
564 };
565 #endif
int long_ref
1->long term reference 0->short term reference
int chroma_qp_index_offset[2]
int luma_weight_flag[2]
7.4.3.2 luma_weight_lX_flag
int chroma_weight[48][2][2][2]
unsigned int ref_count[2]
num_ref_idx_l0/1_active_minus1 + 1
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
H264Picture * long_ref[32]
#define D3D11VA_CONTEXT(ctx)
unsigned int ref_count[2]
num_ref_idx_l0/1_active_minus1 + 1
static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice, const DXVA_PicParams_H264 *pp, unsigned position, unsigned size)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
uint8_t scaling_matrix4[6][16]
int deblocking_filter_parameters_present
deblocking_filter_parameters_present_flag
int ff_dxva2_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
int ff_dxva2_decode_uninit(AVCodecContext *avctx)
int slice_alpha_c0_offset
int bit_depth_chroma
bit_depth_chroma_minus8 + 8
static av_cold int end(AVCodecContext *avctx)
int chroma_weight_flag[2]
7.4.3.2 chroma_weight_lX_flag
static int is_slice_short(const AVCodecContext *avctx, AVDXVAContext *ctx)
int cabac
entropy_coding_mode_flag
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 *, DECODER_BUFFER_DESC *bs, DECODER_BUFFER_DESC *slice))
#define PICT_BOTTOM_FIELD
static int get_bits_count(const GetBitContext *s)
int redundant_pic_cnt_present
redundant_pic_cnt_present_flag
const AVHWAccel ff_h264_d3d11va_hwaccel
int luma_weight[48][2][2]
DXVA_SliceInfo slice[MAX_SLICES]
#define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG
Work around for Direct3D11 and old UVD/UVD+ ATI video cards.
void ff_h264_draw_horiz_band(const H264Context *h, H264SliceContext *sl, int y, int height)
H.264 parameter set handling.
int mb_aff
mb_adaptive_frame_field_flag
int chroma_log2_weight_denom
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int poc_type
pic_order_cnt_type
int constrained_intra_pred
constrained_intra_pred_flag
void * hwaccel_picture_private
hardware accelerator private data
const uint8_t ff_zigzag_scan[16+1]
int ff_dxva2_is_d3d11(const AVCodecContext *avctx)
int deblocking_filter
disable_deblocking_filter_idc with 1 <-> 0
#define DXVA2_CONTEXT(ctx)
simple assert() macros that are a bit more flexible than ISO C assert().
int weighted_pred
weighted_pred_flag
int direct_spatial_mv_pred
int frame_num
frame_num (raw frame_num from slice header)
int residual_color_transform_flag
residual_colour_transform_flag
int ff_h264_get_slice_type(const H264SliceContext *sl)
Reconstruct bitstream slice_type.
int delta_pic_order_always_zero_flag
static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, const H264Context *h, DXVA_PicParams_H264 *pp)
uint8_t scaling_matrix8[6][64]
int ref_frame_count
num_ref_frames
const char * name
Name of the hardware accelerated codec.
static const chunk_decoder decoder[8]
#define FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO
Work around for Direct3D11 and old Intel GPUs with ClearVideo interface.
int luma_log2_weight_denom
int init_qp
pic_init_qp_minus26 + 26
int ff_dxva2_decode_init(AVCodecContext *avctx)
H.264 / AVC / MPEG-4 part10 codec.
H264SliceContext * slice_ctx
int direct_8x8_inference_flag
#define FIELD_OR_MBAFF_PICTURE(h)
#define FF_ARRAY_ELEMS(a)
DXVA_Slice_H264_Long slice_long[MAX_SLICES]
int pic_order_present
pic_order_present_flag
static void fill_slice_short(DXVA_Slice_H264_Short *slice, unsigned position, unsigned size)
static int get_refpic_index(const DXVA_PicParams_H264 *pp, int surface_index)
H264Picture * short_ref[32]
unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx, const AVDXVAContext *ctx, const AVFrame *frame)
int field_poc[2]
top/bottom POC
main external API structure.
int ff_dxva2_commit_buffer(AVCodecContext *avctx, AVDXVAContext *ctx, DECODER_BUFFER_DESC *dsc, unsigned type, const void *data, unsigned size, unsigned mb_count)
static int FUNC() pps(CodedBitstreamContext *ctx, RWContext *rw, H264RawPPS *current)
H264Picture * cur_pic_ptr
static void fill_scaling_lists(const AVCodecContext *avctx, AVDXVAContext *ctx, const H264Context *h, DXVA_Qmatrix_H264 *qm)
const uint8_t ff_zigzag_direct[64]
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
int log2_max_poc_lsb
log2_max_pic_order_cnt_lsb_minus4
HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer. ...
static int dxva2_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
int transform_8x8_mode
transform_8x8_mode_flag
const AVHWAccel ff_h264_dxva2_hwaccel
Hardware surfaces for Direct3D11.
static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, DECODER_BUFFER_DESC *bs, DECODER_BUFFER_DESC *sc)
const uint8_t * bitstream
int init_qs
pic_init_qs_minus26 + 26
int pic_id
pic_num (short -> no wrap version of pic_num, pic_num & max_pic_num; long -> long_pic_num) ...
const AVHWAccel ff_h264_d3d11va2_hwaccel
int log2_max_frame_num
log2_max_frame_num_minus4 + 4
int bit_depth_luma
bit_depth_luma_minus8 + 8
static int dxva2_h264_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
static int dxva2_h264_end_frame(AVCodecContext *avctx)
int current_slice
current slice number, used to initialize slice_num of each thread/context
#define DXVA_CONTEXT(avctx)
int slice_group_count
num_slice_groups_minus1 + 1
H264Ref ref_list[2][48]
0..15: frame refs, 16..47: mbaff field refs.
HW decoding through Direct3D11 via old API, Picture.data[3] contains a ID3D11VideoDecoderOutputView p...
DXVA_Slice_H264_Short slice_short[MAX_SLICES]
static void fill_picture_entry(DXVA_PicEntry_H264 *pic, unsigned index, unsigned flag)
int short_ref_count
number of actual short term references
int mb_slice_group_map_type