annotate ffmpeg/libavcodec/dxva2.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * DXVA2 HW acceleration.
yading@10 3 *
yading@10 4 * copyright (c) 2010 Laurent Aimar
yading@10 5 *
yading@10 6 * This file is part of FFmpeg.
yading@10 7 *
yading@10 8 * FFmpeg is free software; you can redistribute it and/or
yading@10 9 * modify it under the terms of the GNU Lesser General Public
yading@10 10 * License as published by the Free Software Foundation; either
yading@10 11 * version 2.1 of the License, or (at your option) any later version.
yading@10 12 *
yading@10 13 * FFmpeg is distributed in the hope that it will be useful,
yading@10 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 16 * Lesser General Public License for more details.
yading@10 17 *
yading@10 18 * You should have received a copy of the GNU Lesser General Public
yading@10 19 * License along with FFmpeg; if not, write to the Free Software
yading@10 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 21 */
yading@10 22
yading@10 23 #include "dxva2_internal.h"
yading@10 24
yading@10 25 void *ff_dxva2_get_surface(const Picture *picture)
yading@10 26 {
yading@10 27 return picture->f.data[3];
yading@10 28 }
yading@10 29
yading@10 30 unsigned ff_dxva2_get_surface_index(const struct dxva_context *ctx,
yading@10 31 const Picture *picture)
yading@10 32 {
yading@10 33 void *surface = ff_dxva2_get_surface(picture);
yading@10 34 unsigned i;
yading@10 35
yading@10 36 for (i = 0; i < ctx->surface_count; i++)
yading@10 37 if (ctx->surface[i] == surface)
yading@10 38 return i;
yading@10 39
yading@10 40 assert(0);
yading@10 41 return 0;
yading@10 42 }
yading@10 43
yading@10 44 int ff_dxva2_commit_buffer(AVCodecContext *avctx,
yading@10 45 struct dxva_context *ctx,
yading@10 46 DXVA2_DecodeBufferDesc *dsc,
yading@10 47 unsigned type, const void *data, unsigned size,
yading@10 48 unsigned mb_count)
yading@10 49 {
yading@10 50 void *dxva_data;
yading@10 51 unsigned dxva_size;
yading@10 52 int result;
yading@10 53
yading@10 54 if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, type,
yading@10 55 &dxva_data, &dxva_size))) {
yading@10 56 av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %d\n", type);
yading@10 57 return -1;
yading@10 58 }
yading@10 59 if (size <= dxva_size) {
yading@10 60 memcpy(dxva_data, data, size);
yading@10 61
yading@10 62 memset(dsc, 0, sizeof(*dsc));
yading@10 63 dsc->CompressedBufferType = type;
yading@10 64 dsc->DataSize = size;
yading@10 65 dsc->NumMBsInBuffer = mb_count;
yading@10 66
yading@10 67 result = 0;
yading@10 68 } else {
yading@10 69 av_log(avctx, AV_LOG_ERROR, "Buffer for type %d was too small\n", type);
yading@10 70 result = -1;
yading@10 71 }
yading@10 72 if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, type))) {
yading@10 73 av_log(avctx, AV_LOG_ERROR, "Failed to release buffer type %d\n", type);
yading@10 74 result = -1;
yading@10 75 }
yading@10 76 return result;
yading@10 77 }
yading@10 78
yading@10 79 int ff_dxva2_common_end_frame(AVCodecContext *avctx, Picture *pic,
yading@10 80 const void *pp, unsigned pp_size,
yading@10 81 const void *qm, unsigned qm_size,
yading@10 82 int (*commit_bs_si)(AVCodecContext *,
yading@10 83 DXVA2_DecodeBufferDesc *bs,
yading@10 84 DXVA2_DecodeBufferDesc *slice))
yading@10 85 {
yading@10 86 struct dxva_context *ctx = avctx->hwaccel_context;
yading@10 87 unsigned buffer_count = 0;
yading@10 88 DXVA2_DecodeBufferDesc buffer[4];
yading@10 89 DXVA2_DecodeExecuteParams exec = { 0 };
yading@10 90 int result;
yading@10 91
yading@10 92 if (FAILED(IDirectXVideoDecoder_BeginFrame(ctx->decoder,
yading@10 93 ff_dxva2_get_surface(pic),
yading@10 94 NULL))) {
yading@10 95 av_log(avctx, AV_LOG_ERROR, "Failed to begin frame\n");
yading@10 96 return -1;
yading@10 97 }
yading@10 98
yading@10 99 result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
yading@10 100 DXVA2_PictureParametersBufferType,
yading@10 101 pp, pp_size, 0);
yading@10 102 if (result) {
yading@10 103 av_log(avctx, AV_LOG_ERROR,
yading@10 104 "Failed to add picture parameter buffer\n");
yading@10 105 goto end;
yading@10 106 }
yading@10 107 buffer_count++;
yading@10 108
yading@10 109 if (qm_size > 0) {
yading@10 110 result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
yading@10 111 DXVA2_InverseQuantizationMatrixBufferType,
yading@10 112 qm, qm_size, 0);
yading@10 113 if (result) {
yading@10 114 av_log(avctx, AV_LOG_ERROR,
yading@10 115 "Failed to add inverse quantization matrix buffer\n");
yading@10 116 goto end;
yading@10 117 }
yading@10 118 buffer_count++;
yading@10 119 }
yading@10 120
yading@10 121 result = commit_bs_si(avctx,
yading@10 122 &buffer[buffer_count + 0],
yading@10 123 &buffer[buffer_count + 1]);
yading@10 124 if (result) {
yading@10 125 av_log(avctx, AV_LOG_ERROR,
yading@10 126 "Failed to add bitstream or slice control buffer\n");
yading@10 127 goto end;
yading@10 128 }
yading@10 129 buffer_count += 2;
yading@10 130
yading@10 131 /* TODO Film Grain when possible */
yading@10 132
yading@10 133 assert(buffer_count == 1 + (qm_size > 0) + 2);
yading@10 134
yading@10 135 exec.NumCompBuffers = buffer_count;
yading@10 136 exec.pCompressedBuffers = buffer;
yading@10 137 exec.pExtensionData = NULL;
yading@10 138 if (FAILED(IDirectXVideoDecoder_Execute(ctx->decoder, &exec))) {
yading@10 139 av_log(avctx, AV_LOG_ERROR, "Failed to execute\n");
yading@10 140 result = -1;
yading@10 141 }
yading@10 142
yading@10 143 end:
yading@10 144 if (FAILED(IDirectXVideoDecoder_EndFrame(ctx->decoder, NULL))) {
yading@10 145 av_log(avctx, AV_LOG_ERROR, "Failed to end frame\n");
yading@10 146 result = -1;
yading@10 147 }
yading@10 148
yading@10 149 return result;
yading@10 150 }