• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/dxva2.c

Go to the documentation of this file.
00001 /*
00002  * DXVA2 HW acceleration.
00003  *
00004  * copyright (c) 2010 Laurent Aimar
00005  *
00006  * This file is part of FFmpeg.
00007  *
00008  * FFmpeg is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * FFmpeg is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with FFmpeg; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00023 #include "dxva2_internal.h"
00024 
00025 void *ff_dxva2_get_surface(const Picture *picture)
00026 {
00027     return picture->data[3];
00028 }
00029 
00030 unsigned ff_dxva2_get_surface_index(const struct dxva_context *ctx,
00031                                     const Picture *picture)
00032 {
00033     void *surface = ff_dxva2_get_surface(picture);
00034     unsigned i;
00035 
00036     for (i = 0; i < ctx->surface_count; i++)
00037         if (ctx->surface[i] == surface)
00038             return i;
00039 
00040     assert(0);
00041     return 0;
00042 }
00043 
00044 int ff_dxva2_commit_buffer(AVCodecContext *avctx,
00045                            struct dxva_context *ctx,
00046                            DXVA2_DecodeBufferDesc *dsc,
00047                            unsigned type, const void *data, unsigned size,
00048                            unsigned mb_count)
00049 {
00050     void     *dxva_data;
00051     unsigned dxva_size;
00052     int      result;
00053 
00054     if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, type,
00055                                               &dxva_data, &dxva_size))) {
00056         av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %d\n", type);
00057         return -1;
00058     }
00059     if (size <= dxva_size) {
00060         memcpy(dxva_data, data, size);
00061 
00062         memset(dsc, 0, sizeof(*dsc));
00063         dsc->CompressedBufferType = type;
00064         dsc->DataSize             = size;
00065         dsc->NumMBsInBuffer       = mb_count;
00066 
00067         result = 0;
00068     } else {
00069         av_log(avctx, AV_LOG_ERROR, "Buffer for type %d was too small\n", type);
00070         result = -1;
00071     }
00072     if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, type))) {
00073         av_log(avctx, AV_LOG_ERROR, "Failed to release buffer type %d\n", type);
00074         result = -1;
00075     }
00076     return result;
00077 }
00078 
00079 int ff_dxva2_common_end_frame(AVCodecContext *avctx, MpegEncContext *s,
00080                               const void *pp, unsigned pp_size,
00081                               const void *qm, unsigned qm_size,
00082                               int (*commit_bs_si)(AVCodecContext *,
00083                                                   DXVA2_DecodeBufferDesc *bs,
00084                                                   DXVA2_DecodeBufferDesc *slice))
00085 {
00086     struct dxva_context *ctx = avctx->hwaccel_context;
00087     unsigned               buffer_count = 0;
00088     DXVA2_DecodeBufferDesc buffer[4];
00089     DXVA2_DecodeExecuteParams exec;
00090     int      result;
00091 
00092     if (FAILED(IDirectXVideoDecoder_BeginFrame(ctx->decoder,
00093                                                ff_dxva2_get_surface(s->current_picture_ptr),
00094                                                NULL))) {
00095         av_log(avctx, AV_LOG_ERROR, "Failed to begin frame\n");
00096         return -1;
00097     }
00098 
00099     result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
00100                                     DXVA2_PictureParametersBufferType,
00101                                     pp, pp_size, 0);
00102     if (result) {
00103         av_log(avctx, AV_LOG_ERROR,
00104                "Failed to add picture parameter buffer\n");
00105         goto end;
00106     }
00107     buffer_count++;
00108 
00109     if (qm_size > 0) {
00110         result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
00111                                         DXVA2_InverseQuantizationMatrixBufferType,
00112                                         qm, qm_size, 0);
00113         if (result) {
00114             av_log(avctx, AV_LOG_ERROR,
00115                    "Failed to add inverse quantization matrix buffer\n");
00116             goto end;
00117         }
00118         buffer_count++;
00119     }
00120 
00121     result = commit_bs_si(avctx,
00122                           &buffer[buffer_count + 0],
00123                           &buffer[buffer_count + 1]);
00124     if (result) {
00125         av_log(avctx, AV_LOG_ERROR,
00126                "Failed to add bitstream or slice control buffer\n");
00127         goto end;
00128     }
00129     buffer_count += 2;
00130 
00131     /* TODO Film Grain when possible */
00132 
00133     assert(buffer_count == 1 + (qm_size > 0) + 2);
00134 
00135     memset(&exec, 0, sizeof(exec));
00136     exec.NumCompBuffers      = buffer_count;
00137     exec.pCompressedBuffers  = buffer;
00138     exec.pExtensionData      = NULL;
00139     if (FAILED(IDirectXVideoDecoder_Execute(ctx->decoder, &exec))) {
00140         av_log(avctx, AV_LOG_ERROR, "Failed to execute\n");
00141         result = -1;
00142     }
00143 
00144 end:
00145     if (FAILED(IDirectXVideoDecoder_EndFrame(ctx->decoder, NULL))) {
00146         av_log(avctx, AV_LOG_ERROR, "Failed to end frame\n");
00147         result = -1;
00148     }
00149 
00150     if (!result)
00151         ff_draw_horiz_band(s, 0, s->avctx->height);
00152     return result;
00153 }
00154 

Generated on Fri Sep 16 2011 17:17:36 for FFmpeg by  doxygen 1.7.1