Originally committed as revision 21407 to svn://svn.ffmpeg.org/ffmpeg/trunkrelease/0.6
parent
0c32e19d58
commit
85167c46ef
4 changed files with 205 additions and 133 deletions
@ -0,0 +1,154 @@ |
||||
/*
|
||||
* DXVA2 HW acceleration. |
||||
* |
||||
* copyright (c) 2010 Laurent Aimar |
||||
* |
||||
* This file is part of FFmpeg. |
||||
* |
||||
* FFmpeg is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* FFmpeg is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with FFmpeg; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#include "dxva2_internal.h" |
||||
|
||||
void *ff_dxva2_get_surface(const Picture *picture) |
||||
{ |
||||
return picture->data[3]; |
||||
} |
||||
|
||||
unsigned ff_dxva2_get_surface_index(const struct dxva_context *ctx, |
||||
const Picture *picture) |
||||
{ |
||||
void *surface = ff_dxva2_get_surface(picture); |
||||
unsigned i; |
||||
|
||||
for (i = 0; i < ctx->surface_count; i++) |
||||
if (ctx->surface[i] == surface) |
||||
return i; |
||||
|
||||
assert(0); |
||||
return 0; |
||||
} |
||||
|
||||
int ff_dxva2_commit_buffer(AVCodecContext *avctx, |
||||
struct dxva_context *ctx, |
||||
DXVA2_DecodeBufferDesc *dsc, |
||||
unsigned type, const void *data, unsigned size, |
||||
unsigned mb_count) |
||||
{ |
||||
void *dxva_data; |
||||
unsigned dxva_size; |
||||
int result; |
||||
|
||||
if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, type, |
||||
&dxva_data, &dxva_size))) { |
||||
av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %d\n", type); |
||||
return -1; |
||||
} |
||||
if (size <= dxva_size) { |
||||
memcpy(dxva_data, data, size); |
||||
|
||||
memset(dsc, 0, sizeof(*dsc)); |
||||
dsc->CompressedBufferType = type; |
||||
dsc->DataSize = size; |
||||
dsc->NumMBsInBuffer = mb_count; |
||||
|
||||
result = 0; |
||||
} else { |
||||
av_log(avctx, AV_LOG_ERROR, "Buffer for type %d was too small\n", type); |
||||
result = -1; |
||||
} |
||||
if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, type))) { |
||||
av_log(avctx, AV_LOG_ERROR, "Failed to release buffer type %d\n", type); |
||||
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; |
||||
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); |
||||
|
||||
memset(&exec, 0, sizeof(exec)); |
||||
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; |
||||
} |
||||
|
@ -0,0 +1,48 @@ |
||||
/*
|
||||
* DXVA2 HW acceleration |
||||
* |
||||
* copyright (c) 2010 Laurent Aimar |
||||
* |
||||
* This file is part of FFmpeg. |
||||
* |
||||
* FFmpeg is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* FFmpeg is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with FFmpeg; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#ifndef AVCODEC_DXVA_INTERNAL_H |
||||
#define AVCODEC_DXVA_INTERNAL_H |
||||
|
||||
#include "dxva2.h" |
||||
#include "avcodec.h" |
||||
#include "mpegvideo.h" |
||||
|
||||
void *ff_dxva2_get_surface(const Picture *picture); |
||||
|
||||
unsigned ff_dxva2_get_surface_index(const struct dxva_context *, |
||||
const Picture *picture); |
||||
|
||||
int ff_dxva2_commit_buffer(AVCodecContext *, struct dxva_context *, |
||||
DXVA2_DecodeBufferDesc *, |
||||
unsigned type, const void *data, unsigned size, |
||||
unsigned mb_count); |
||||
|
||||
|
||||
int ff_dxva2_common_end_frame(AVCodecContext *, MpegEncContext *, |
||||
const void *pp, unsigned pp_size, |
||||
const void *qm, unsigned qm_size, |
||||
int (*commit_bs_si)(AVCodecContext *, |
||||
DXVA2_DecodeBufferDesc *bs, |
||||
DXVA2_DecodeBufferDesc *slice)); |
||||
|
||||
#endif /* AVCODEC_DXVA_INTERNAL_H */ |
Loading…
Reference in new issue