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 23#include "config_components.h" 24 25#include "libavutil/avassert.h" 26 27#include "dxva2_internal.h" 28#include "h264dec.h" 29#include "h264data.h" 30#include "h264_ps.h" 31#include "mpegutils.h" 32 33struct dxva2_picture_context { 34 DXVA_PicParams_H264 pp; 35 DXVA_Qmatrix_H264 qm; 36 unsigned slice_count; 37 DXVA_Slice_H264_Short slice_short[MAX_SLICES]; 38 DXVA_Slice_H264_Long slice_long[MAX_SLICES]; 39 const uint8_t *bitstream; 40 unsigned bitstream_size; 41}; 42 43static void fill_picture_entry(DXVA_PicEntry_H264 *pic, 44 unsigned index, unsigned flag) 45{ 46 assert((index&0x7f) == index && (flag&0x01) == flag); 47 pic->bPicEntry = index | (flag << 7); 48} 49 50static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, const H264Context *h, 51 DXVA_PicParams_H264 *pp) 52{ 53 const H264Picture *current_picture = h->cur_pic_ptr; 54 const SPS *sps = h->ps.sps; 55 const PPS *pps = h->ps.pps; 56 int i, j; 57 58 memset(pp, 0, sizeof(*pp)); 59 /* Configure current picture */ 60 fill_picture_entry(&pp->CurrPic, 61 ff_dxva2_get_surface_index(avctx, ctx, current_picture->f), 62 h->picture_structure == PICT_BOTTOM_FIELD); 63 /* Configure the set of references */ 64 pp->UsedForReferenceFlags = 0; 65 pp->NonExistingFrameFlags = 0; 66 for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->RefFrameList); i++) { 67 const H264Picture *r; 68 if (j < h->short_ref_count) { 69 r = h->short_ref[j++]; 70 } else { 71 r = NULL; 72 while (!r && j < h->short_ref_count + 16) 73 r = h->long_ref[j++ - h->short_ref_count]; 74 } 75 if (r) { 76 fill_picture_entry(&pp->RefFrameList[i], 77 ff_dxva2_get_surface_index(avctx, ctx, r->f), 78 r->long_ref != 0); 79 80 if ((r->reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX) 81 pp->FieldOrderCntList[i][0] = r->field_poc[0]; 82 if ((r->reference & PICT_BOTTOM_FIELD) && r->field_poc[1] != INT_MAX) 83 pp->FieldOrderCntList[i][1] = r->field_poc[1]; 84 85 pp->FrameNumList[i] = r->long_ref ? r->pic_id : r->frame_num; 86 if (r->reference & PICT_TOP_FIELD) 87 pp->UsedForReferenceFlags |= 1 << (2*i + 0); 88 if (r->reference & PICT_BOTTOM_FIELD) 89 pp->UsedForReferenceFlags |= 1 << (2*i + 1); 90 } else { 91 pp->RefFrameList[i].bPicEntry = 0xff; 92 pp->FieldOrderCntList[i][0] = 0; 93 pp->FieldOrderCntList[i][1] = 0; 94 pp->FrameNumList[i] = 0; 95 } 96 } 97 98 pp->wFrameWidthInMbsMinus1 = h->mb_width - 1; 99 pp->wFrameHeightInMbsMinus1 = h->mb_height - 1; 100 pp->num_ref_frames = sps->ref_frame_count; 101 102 pp->wBitFields = ((h->picture_structure != PICT_FRAME) << 0) | 103 ((sps->mb_aff && 104 (h->picture_structure == PICT_FRAME)) << 1) | 105 (sps->residual_color_transform_flag << 2) | 106 /* sp_for_switch_flag (not implemented by FFmpeg) */ 107 (0 << 3) | 108 (sps->chroma_format_idc << 4) | 109 ((h->nal_ref_idc != 0) << 6) | 110 (pps->constrained_intra_pred << 7) | 111 (pps->weighted_pred << 8) | 112 (pps->weighted_bipred_idc << 9) | 113 /* MbsConsecutiveFlag */ 114 (1 << 11) | 115 (sps->frame_mbs_only_flag << 12) | 116 (pps->transform_8x8_mode << 13) | 117 ((sps->level_idc >= 31) << 14) | 118 /* IntraPicFlag (Modified if we detect a non 119 * intra slice in dxva2_h264_decode_slice) */ 120 (1 << 15); 121 122 pp->bit_depth_luma_minus8 = sps->bit_depth_luma - 8; 123 pp->bit_depth_chroma_minus8 = sps->bit_depth_chroma - 8; 124 if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) 125 pp->Reserved16Bits = 0; 126 else if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO) 127 pp->Reserved16Bits = 0x34c; 128 else 129 pp->Reserved16Bits = 3; /* FIXME is there a way to detect the right mode ? */ 130 pp->StatusReportFeedbackNumber = 1 + DXVA_CONTEXT_REPORT_ID(avctx, ctx)++; 131 pp->CurrFieldOrderCnt[0] = 0; 132 if ((h->picture_structure & PICT_TOP_FIELD) && 133 current_picture->field_poc[0] != INT_MAX) 134 pp->CurrFieldOrderCnt[0] = current_picture->field_poc[0]; 135 pp->CurrFieldOrderCnt[1] = 0; 136 if ((h->picture_structure & PICT_BOTTOM_FIELD) && 137 current_picture->field_poc[1] != INT_MAX) 138 pp->CurrFieldOrderCnt[1] = current_picture->field_poc[1]; 139 pp->pic_init_qs_minus26 = pps->init_qs - 26; 140 pp->chroma_qp_index_offset = pps->chroma_qp_index_offset[0]; 141 pp->second_chroma_qp_index_offset = pps->chroma_qp_index_offset[1]; 142 pp->ContinuationFlag = 1; 143 pp->pic_init_qp_minus26 = pps->init_qp - 26; 144 pp->num_ref_idx_l0_active_minus1 = pps->ref_count[0] - 1; 145 pp->num_ref_idx_l1_active_minus1 = pps->ref_count[1] - 1; 146 pp->Reserved8BitsA = 0; 147 pp->frame_num = h->poc.frame_num; 148 pp->log2_max_frame_num_minus4 = sps->log2_max_frame_num - 4; 149 pp->pic_order_cnt_type = sps->poc_type; 150 if (sps->poc_type == 0) 151 pp->log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4; 152 else if (sps->poc_type == 1) 153 pp->delta_pic_order_always_zero_flag = sps->delta_pic_order_always_zero_flag; 154 pp->direct_8x8_inference_flag = sps->direct_8x8_inference_flag; 155 pp->entropy_coding_mode_flag = pps->cabac; 156 pp->pic_order_present_flag = pps->pic_order_present; 157 pp->num_slice_groups_minus1 = pps->slice_group_count - 1; 158 pp->slice_group_map_type = pps->mb_slice_group_map_type; 159 pp->deblocking_filter_control_present_flag = pps->deblocking_filter_parameters_present; 160 pp->redundant_pic_cnt_present_flag= pps->redundant_pic_cnt_present; 161 pp->Reserved8BitsB = 0; 162 pp->slice_group_change_rate_minus1= 0; /* XXX not implemented by FFmpeg */ 163 //pp->SliceGroupMap[810]; /* XXX not implemented by FFmpeg */ 164} 165 166static void fill_scaling_lists(const AVCodecContext *avctx, AVDXVAContext *ctx, const H264Context *h, DXVA_Qmatrix_H264 *qm) 167{ 168 const PPS *pps = h->ps.pps; 169 unsigned i, j; 170 memset(qm, 0, sizeof(*qm)); 171 if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) { 172 for (i = 0; i < 6; i++) 173 for (j = 0; j < 16; j++) 174 qm->bScalingLists4x4[i][j] = pps->scaling_matrix4[i][j]; 175 176 for (i = 0; i < 64; i++) { 177 qm->bScalingLists8x8[0][i] = pps->scaling_matrix8[0][i]; 178 qm->bScalingLists8x8[1][i] = pps->scaling_matrix8[3][i]; 179 } 180 } else { 181 for (i = 0; i < 6; i++) 182 for (j = 0; j < 16; j++) 183 qm->bScalingLists4x4[i][j] = pps->scaling_matrix4[i][ff_zigzag_scan[j]]; 184 185 for (i = 0; i < 64; i++) { 186 qm->bScalingLists8x8[0][i] = pps->scaling_matrix8[0][ff_zigzag_direct[i]]; 187 qm->bScalingLists8x8[1][i] = pps->scaling_matrix8[3][ff_zigzag_direct[i]]; 188 } 189 } 190} 191 192static int is_slice_short(const AVCodecContext *avctx, AVDXVAContext *ctx) 193{ 194 assert(DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) == 1 || 195 DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) == 2); 196 return DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) == 2; 197} 198 199static void fill_slice_short(DXVA_Slice_H264_Short *slice, 200 unsigned position, unsigned size) 201{ 202 memset(slice, 0, sizeof(*slice)); 203 slice->BSNALunitDataLocation = position; 204 slice->SliceBytesInBuffer = size; 205 slice->wBadSliceChopping = 0; 206} 207 208static int get_refpic_index(const DXVA_PicParams_H264 *pp, int surface_index) 209{ 210 int i; 211 for (i = 0; i < FF_ARRAY_ELEMS(pp->RefFrameList); i++) { 212 if ((pp->RefFrameList[i].bPicEntry & 0x7f) == surface_index) 213 return i; 214 } 215 return 0x7f; 216} 217 218static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice, 219 const DXVA_PicParams_H264 *pp, unsigned position, unsigned size) 220{ 221 const H264Context *h = avctx->priv_data; 222 H264SliceContext *sl = &h->slice_ctx[0]; 223 AVDXVAContext *ctx = DXVA_CONTEXT(avctx); 224 unsigned list; 225 226 memset(slice, 0, sizeof(*slice)); 227 slice->BSNALunitDataLocation = position; 228 slice->SliceBytesInBuffer = size; 229 slice->wBadSliceChopping = 0; 230 231 slice->first_mb_in_slice = (sl->mb_y >> FIELD_OR_MBAFF_PICTURE(h)) * h->mb_width + sl->mb_x; 232 slice->NumMbsForSlice = 0; /* XXX it is set once we have all slices */ 233 slice->BitOffsetToSliceData = get_bits_count(&sl->gb) - 8; 234 slice->slice_type = ff_h264_get_slice_type(sl); 235 if (sl->slice_type_fixed) 236 slice->slice_type += 5; 237 slice->luma_log2_weight_denom = sl->pwt.luma_log2_weight_denom; 238 slice->chroma_log2_weight_denom = sl->pwt.chroma_log2_weight_denom; 239 if (sl->list_count > 0) 240 slice->num_ref_idx_l0_active_minus1 = sl->ref_count[0] - 1; 241 if (sl->list_count > 1) 242 slice->num_ref_idx_l1_active_minus1 = sl->ref_count[1] - 1; 243 slice->slice_alpha_c0_offset_div2 = sl->slice_alpha_c0_offset / 2; 244 slice->slice_beta_offset_div2 = sl->slice_beta_offset / 2; 245 slice->Reserved8Bits = 0; 246 247 for (list = 0; list < 2; list++) { 248 unsigned i; 249 for (i = 0; i < FF_ARRAY_ELEMS(slice->RefPicList[list]); i++) { 250 if (list < sl->list_count && i < sl->ref_count[list]) { 251 const H264Picture *r = sl->ref_list[list][i].parent; 252 unsigned plane; 253 unsigned index; 254 if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO) 255 index = ff_dxva2_get_surface_index(avctx, ctx, r->f); 256 else 257 index = get_refpic_index(pp, ff_dxva2_get_surface_index(avctx, ctx, r->f)); 258 fill_picture_entry(&slice->RefPicList[list][i], index, 259 sl->ref_list[list][i].reference == PICT_BOTTOM_FIELD); 260 for (plane = 0; plane < 3; plane++) { 261 int w, o; 262 if (plane == 0 && sl->pwt.luma_weight_flag[list]) { 263 w = sl->pwt.luma_weight[i][list][0]; 264 o = sl->pwt.luma_weight[i][list][1]; 265 } else if (plane >= 1 && sl->pwt.chroma_weight_flag[list]) { 266 w = sl->pwt.chroma_weight[i][list][plane-1][0]; 267 o = sl->pwt.chroma_weight[i][list][plane-1][1]; 268 } else { 269 w = 1 << (plane == 0 ? sl->pwt.luma_log2_weight_denom : 270 sl->pwt.chroma_log2_weight_denom); 271 o = 0; 272 } 273 slice->Weights[list][i][plane][0] = w; 274 slice->Weights[list][i][plane][1] = o; 275 } 276 } else { 277 unsigned plane; 278 slice->RefPicList[list][i].bPicEntry = 0xff; 279 for (plane = 0; plane < 3; plane++) { 280 slice->Weights[list][i][plane][0] = 0; 281 slice->Weights[list][i][plane][1] = 0; 282 } 283 } 284 } 285 } 286 slice->slice_qs_delta = 0; /* XXX not implemented by FFmpeg */ 287 slice->slice_qp_delta = sl->qscale - h->ps.pps->init_qp; 288 slice->redundant_pic_cnt = sl->redundant_pic_count; 289 if (sl->slice_type == AV_PICTURE_TYPE_B) 290 slice->direct_spatial_mv_pred_flag = sl->direct_spatial_mv_pred; 291 slice->cabac_init_idc = h->ps.pps->cabac ? sl->cabac_init_idc : 0; 292 if (sl->deblocking_filter < 2) 293 slice->disable_deblocking_filter_idc = 1 - sl->deblocking_filter; 294 else 295 slice->disable_deblocking_filter_idc = sl->deblocking_filter; 296 slice->slice_id = h->current_slice - 1; 297} 298 299static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, 300 DECODER_BUFFER_DESC *bs, 301 DECODER_BUFFER_DESC *sc) 302{ 303 const H264Context *h = avctx->priv_data; 304 const unsigned mb_count = h->mb_width * h->mb_height; 305 AVDXVAContext *ctx = DXVA_CONTEXT(avctx); 306 const H264Picture *current_picture = h->cur_pic_ptr; 307 struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private; 308 DXVA_Slice_H264_Short *slice = NULL; 309 void *dxva_data_ptr = NULL; 310 uint8_t *dxva_data, *current, *end; 311 unsigned dxva_size = 0; 312 void *slice_data; 313 unsigned slice_size; 314 unsigned padding; 315 unsigned i; 316 unsigned type; 317 318 /* Create an annex B bitstream buffer with only slice NAL and finalize slice */ 319#if CONFIG_D3D11VA 320 if (ff_dxva2_is_d3d11(avctx)) { 321 type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM; 322 if (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, 323 D3D11VA_CONTEXT(ctx)->decoder, 324 type, 325 &dxva_size, &dxva_data_ptr))) 326 return -1; 327 } 328#endif 329#if CONFIG_DXVA2 330 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { 331 type = DXVA2_BitStreamDateBufferType; 332 if (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder, 333 type, 334 &dxva_data_ptr, &dxva_size))) 335 return -1; 336 } 337#endif 338 339 dxva_data = dxva_data_ptr; 340 current = dxva_data; 341 end = dxva_data + dxva_size; 342 343 for (i = 0; i < ctx_pic->slice_count; i++) { 344 static const uint8_t start_code[] = { 0, 0, 1 }; 345 static const unsigned start_code_size = sizeof(start_code); 346 unsigned position, size; 347 348 assert(offsetof(DXVA_Slice_H264_Short, BSNALunitDataLocation) == 349 offsetof(DXVA_Slice_H264_Long, BSNALunitDataLocation)); 350 assert(offsetof(DXVA_Slice_H264_Short, SliceBytesInBuffer) == 351 offsetof(DXVA_Slice_H264_Long, SliceBytesInBuffer)); 352 353 if (is_slice_short(avctx, ctx)) 354 slice = &ctx_pic->slice_short[i]; 355 else 356 slice = (DXVA_Slice_H264_Short*)&ctx_pic->slice_long[i]; 357 358 position = slice->BSNALunitDataLocation; 359 size = slice->SliceBytesInBuffer; 360 if (start_code_size + size > end - current) { 361 av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream"); 362 break; 363 } 364 365 slice->BSNALunitDataLocation = current - dxva_data; 366 slice->SliceBytesInBuffer = start_code_size + size; 367 368 if (!is_slice_short(avctx, ctx)) { 369 DXVA_Slice_H264_Long *slice_long = (DXVA_Slice_H264_Long*)slice; 370 if (i < ctx_pic->slice_count - 1) 371 slice_long->NumMbsForSlice = 372 slice_long[1].first_mb_in_slice - slice_long[0].first_mb_in_slice; 373 else 374 slice_long->NumMbsForSlice = mb_count - slice_long->first_mb_in_slice; 375 } 376 377 memcpy(current, start_code, start_code_size); 378 current += start_code_size; 379 380 memcpy(current, &ctx_pic->bitstream[position], size); 381 current += size; 382 } 383 padding = FFMIN(128 - ((current - dxva_data) & 127), end - current); 384 if (slice && padding > 0) { 385 memset(current, 0, padding); 386 current += padding; 387 388 slice->SliceBytesInBuffer += padding; 389 } 390#if CONFIG_D3D11VA 391 if (ff_dxva2_is_d3d11(avctx)) 392 if (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type))) 393 return -1; 394#endif 395#if CONFIG_DXVA2 396 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) 397 if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type))) 398 return -1; 399#endif 400 if (i < ctx_pic->slice_count) 401 return -1; 402 403#if CONFIG_D3D11VA 404 if (ff_dxva2_is_d3d11(avctx)) { 405 D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs; 406 memset(dsc11, 0, sizeof(*dsc11)); 407 dsc11->BufferType = type; 408 dsc11->DataSize = current - dxva_data; 409 dsc11->NumMBsInBuffer = mb_count; 410 411 type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL; 412 413 av_assert0((dsc11->DataSize & 127) == 0); 414 } 415#endif 416#if CONFIG_DXVA2 417 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { 418 DXVA2_DecodeBufferDesc *dsc2 = bs; 419 memset(dsc2, 0, sizeof(*dsc2)); 420 dsc2->CompressedBufferType = type; 421 dsc2->DataSize = current - dxva_data; 422 dsc2->NumMBsInBuffer = mb_count; 423 424 type = DXVA2_SliceControlBufferType; 425 426 av_assert0((dsc2->DataSize & 127) == 0); 427 } 428#endif 429 430 if (is_slice_short(avctx, ctx)) { 431 slice_data = ctx_pic->slice_short; 432 slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short); 433 } else { 434 slice_data = ctx_pic->slice_long; 435 slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_long); 436 } 437 return ff_dxva2_commit_buffer(avctx, ctx, sc, 438 type, 439 slice_data, slice_size, mb_count); 440} 441 442 443static int dxva2_h264_start_frame(AVCodecContext *avctx, 444 av_unused const uint8_t *buffer, 445 av_unused uint32_t size) 446{ 447 const H264Context *h = avctx->priv_data; 448 AVDXVAContext *ctx = DXVA_CONTEXT(avctx); 449 struct dxva2_picture_context *ctx_pic = h->cur_pic_ptr->hwaccel_picture_private; 450 451 if (!DXVA_CONTEXT_VALID(avctx, ctx)) 452 return -1; 453 assert(ctx_pic); 454 455 /* Fill up DXVA_PicParams_H264 */ 456 fill_picture_parameters(avctx, ctx, h, &ctx_pic->pp); 457 458 /* Fill up DXVA_Qmatrix_H264 */ 459 fill_scaling_lists(avctx, ctx, h, &ctx_pic->qm); 460 461 ctx_pic->slice_count = 0; 462 ctx_pic->bitstream_size = 0; 463 ctx_pic->bitstream = NULL; 464 return 0; 465} 466 467static int dxva2_h264_decode_slice(AVCodecContext *avctx, 468 const uint8_t *buffer, 469 uint32_t size) 470{ 471 const H264Context *h = avctx->priv_data; 472 const H264SliceContext *sl = &h->slice_ctx[0]; 473 AVDXVAContext *ctx = DXVA_CONTEXT(avctx); 474 const H264Picture *current_picture = h->cur_pic_ptr; 475 struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private; 476 unsigned position; 477 478 if (ctx_pic->slice_count >= MAX_SLICES) 479 return -1; 480 481 if (!ctx_pic->bitstream) 482 ctx_pic->bitstream = buffer; 483 ctx_pic->bitstream_size += size; 484 485 position = buffer - ctx_pic->bitstream; 486 if (is_slice_short(avctx, ctx)) 487 fill_slice_short(&ctx_pic->slice_short[ctx_pic->slice_count], 488 position, size); 489 else 490 fill_slice_long(avctx, &ctx_pic->slice_long[ctx_pic->slice_count], 491 &ctx_pic->pp, position, size); 492 ctx_pic->slice_count++; 493 494 if (sl->slice_type != AV_PICTURE_TYPE_I && sl->slice_type != AV_PICTURE_TYPE_SI) 495 ctx_pic->pp.wBitFields &= ~(1 << 15); /* Set IntraPicFlag to 0 */ 496 return 0; 497} 498 499static int dxva2_h264_end_frame(AVCodecContext *avctx) 500{ 501 H264Context *h = avctx->priv_data; 502 H264SliceContext *sl = &h->slice_ctx[0]; 503 struct dxva2_picture_context *ctx_pic = 504 h->cur_pic_ptr->hwaccel_picture_private; 505 int ret; 506 507 if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0) 508 return -1; 509 ret = ff_dxva2_common_end_frame(avctx, h->cur_pic_ptr->f, 510 &ctx_pic->pp, sizeof(ctx_pic->pp), 511 &ctx_pic->qm, sizeof(ctx_pic->qm), 512 commit_bitstream_and_slice_buffer); 513 if (!ret) 514 ff_h264_draw_horiz_band(h, sl, 0, h->avctx->height); 515 return ret; 516} 517 518#if CONFIG_H264_DXVA2_HWACCEL 519const AVHWAccel ff_h264_dxva2_hwaccel = { 520 .name = "h264_dxva2", 521 .type = AVMEDIA_TYPE_VIDEO, 522 .id = AV_CODEC_ID_H264, 523 .pix_fmt = AV_PIX_FMT_DXVA2_VLD, 524 .init = ff_dxva2_decode_init, 525 .uninit = ff_dxva2_decode_uninit, 526 .start_frame = dxva2_h264_start_frame, 527 .decode_slice = dxva2_h264_decode_slice, 528 .end_frame = dxva2_h264_end_frame, 529 .frame_params = ff_dxva2_common_frame_params, 530 .frame_priv_data_size = sizeof(struct dxva2_picture_context), 531 .priv_data_size = sizeof(FFDXVASharedContext), 532}; 533#endif 534 535#if CONFIG_H264_D3D11VA_HWACCEL 536const AVHWAccel ff_h264_d3d11va_hwaccel = { 537 .name = "h264_d3d11va", 538 .type = AVMEDIA_TYPE_VIDEO, 539 .id = AV_CODEC_ID_H264, 540 .pix_fmt = AV_PIX_FMT_D3D11VA_VLD, 541 .init = ff_dxva2_decode_init, 542 .uninit = ff_dxva2_decode_uninit, 543 .start_frame = dxva2_h264_start_frame, 544 .decode_slice = dxva2_h264_decode_slice, 545 .end_frame = dxva2_h264_end_frame, 546 .frame_params = ff_dxva2_common_frame_params, 547 .frame_priv_data_size = sizeof(struct dxva2_picture_context), 548 .priv_data_size = sizeof(FFDXVASharedContext), 549}; 550#endif 551 552#if CONFIG_H264_D3D11VA2_HWACCEL 553const AVHWAccel ff_h264_d3d11va2_hwaccel = { 554 .name = "h264_d3d11va2", 555 .type = AVMEDIA_TYPE_VIDEO, 556 .id = AV_CODEC_ID_H264, 557 .pix_fmt = AV_PIX_FMT_D3D11, 558 .init = ff_dxva2_decode_init, 559 .uninit = ff_dxva2_decode_uninit, 560 .start_frame = dxva2_h264_start_frame, 561 .decode_slice = dxva2_h264_decode_slice, 562 .end_frame = dxva2_h264_end_frame, 563 .frame_params = ff_dxva2_common_frame_params, 564 .frame_priv_data_size = sizeof(struct dxva2_picture_context), 565 .priv_data_size = sizeof(FFDXVASharedContext), 566}; 567#endif 568