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)) { AVDXVAContext *ctx = avctx->hwaccel_context; unsigned buffer_count = 0; #if CONFIG_D3D11VA D3D11_VIDEO_DECODER_BUFFER_DESC buffer11[4]; #endif #if CONFIG_DXVA2 DXVA2_DecodeBufferDesc buffer2[4]; #endif DECODER_BUFFER_DESC *buffer = NULL, *buffer_slice = NULL; int result, runs = 0; HRESULT hr; unsigned type; do { #if CONFIG_D3D11VA if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) hr = ID3D11VideoContext_DecoderBeginFrame(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, ff_dxva2_get_surface(frame), 0, NULL); #endif #if CONFIG_DXVA2 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) hr = IDirectXVideoDecoder_BeginFrame(DXVA2_CONTEXT(ctx)->decoder, ff_dxva2_get_surface(frame), NULL); #endif 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; } #if CONFIG_D3D11VA if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) { buffer = &buffer11[buffer_count]; type = D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS; } #endif #if CONFIG_DXVA2 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { buffer = &buffer2[buffer_count]; type = DXVA2_PictureParametersBufferType; } #endif result = ff_dxva2_commit_buffer(avctx, ctx, buffer, type, 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) { #if CONFIG_D3D11VA if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) { buffer = &buffer11[buffer_count]; type = D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX; } #endif #if CONFIG_DXVA2 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { buffer = &buffer2[buffer_count]; type = DXVA2_InverseQuantizationMatrixBufferType; } #endif result = ff_dxva2_commit_buffer(avctx, ctx, buffer, type, qm, qm_size, 0); if (result) { av_log(avctx, AV_LOG_ERROR, "Failed to add inverse quantization matrix buffer\n"); goto end; } buffer_count++; } #if CONFIG_D3D11VA if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) { buffer = &buffer11[buffer_count + 0]; buffer_slice = &buffer11[buffer_count + 1]; } #endif #if CONFIG_DXVA2 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { buffer = &buffer2[buffer_count + 0]; buffer_slice = &buffer2[buffer_count + 1]; } #endif result = commit_bs_si(avctx, buffer, buffer_slice); 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); #if CONFIG_D3D11VA if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) hr = ID3D11VideoContext_SubmitDecoderBuffers(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, buffer_count, buffer11); #endif #if CONFIG_DXVA2 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { DXVA2_DecodeExecuteParams exec = { .NumCompBuffers = buffer_count, .pCompressedBuffers = buffer2, .pExtensionData = NULL, }; hr = IDirectXVideoDecoder_Execute(DXVA2_CONTEXT(ctx)->decoder, &exec); }
int ff_dxva2_common_end_frame(AVCodecContext *avctx, Picture *pic, 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(pic), 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%x\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%x\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%x\n", hr); result = -1; } return result; }
int ff_dxva2_common_end_frame(AVCodecContext *avctx, MpegEncContext *s, 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; if (FAILED(IDirectXVideoDecoder_BeginFrame(ctx->decoder, ff_dxva2_get_surface(s->current_picture_ptr), NULL))) { av_log(avctx, AV_LOG_ERROR, "Failed to begin frame\n"); 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; if (FAILED(IDirectXVideoDecoder_Execute(ctx->decoder, &exec))) { av_log(avctx, AV_LOG_ERROR, "Failed to execute\n"); result = -1; } end: if (FAILED(IDirectXVideoDecoder_EndFrame(ctx->decoder, NULL))) { av_log(avctx, AV_LOG_ERROR, "Failed to end frame\n"); result = -1; } if (!result) ff_draw_horiz_band(s, 0, s->avctx->height); return result; }