Quoting wm4 (2016-05-03 16:39:02)
> On Tue, 3 May 2016 14:56:08 +0200
> Anton Khirnov <[email protected]> wrote:
> > +static int dxva2_transfer_data(AVHWFramesContext *ctx, AVFrame *dst,
> > + const AVFrame *src)
> > +{
> > + IDirect3DSurface9 *surface;
> > + D3DSURFACE_DESC surfaceDesc;
> > + D3DLOCKED_RECT LockedRect;
> > + HRESULT hr;
> > +
> > + int download = !!src->hw_frames_ctx;
> > +
> > + surface = (IDirect3DSurface9*)(download ? src->data[3] : dst->data[3]);
> > +
> > + hr = IDirect3DSurface9_GetDesc(surface, &surfaceDesc);
> > + if (FAILED(hr)) {
> > + av_log(ctx, AV_LOG_ERROR, "Error getting a surface description\n");
> > + return AVERROR_UNKNOWN;
> > + }
> > +
> > + hr = IDirect3DSurface9_LockRect(surface, &LockedRect, NULL,
> > D3DLOCK_READONLY);
> > + if (FAILED(hr)) {
> > + av_log(ctx, AV_LOG_ERROR, "Unable to lock DXVA2 surface\n");
> > + return AVERROR_UNKNOWN;
> > + }
> > +
> > + if (download) {
> > + av_image_copy_plane(dst->data[0], dst->linesize[0],
> > + (uint8_t*)LockedRect.pBits, LockedRect.Pitch,
> > + src->width, src->height);
> > + av_image_copy_plane(dst->data[1], dst->linesize[1],
> > + (uint8_t*)LockedRect.pBits + LockedRect.Pitch
> > * surfaceDesc.Height,
> > + LockedRect.Pitch, src->width, src->height / 2);
> > + } else {
> > + av_image_copy_plane((uint8_t*)LockedRect.pBits, LockedRect.Pitch,
> > + dst->data[0], dst->linesize[0],
> > + src->width, src->height);
> > + av_image_copy_plane((uint8_t*)LockedRect.pBits + LockedRect.Pitch
> > * surfaceDesc.Height,
> > + LockedRect.Pitch, dst->data[1],
> > dst->linesize[1],
> > + src->width, src->height / 2);
> > + }
>
> This should probably use a magic GPU memcpy.
When we add it, sure. Same goes for vaapi I think.
>
> > +
> > + IDirect3DSurface9_UnlockRect(surface);
> > +
> > + return 0;
> > +}
> > +
> > +const HWContextType ff_hwcontext_type_dxva2 = {
> > + .type = AV_HWDEVICE_TYPE_DXVA2,
> > + .name = "DXVA2",
> > +
> > + .device_hwctx_size = sizeof(AVDXVA2DeviceContext),
> > + .frames_hwctx_size = sizeof(AVDXVA2FramesContext),
> > + .frames_priv_size = sizeof(DXVA2FramesContext),
> > +
> > + .frames_init = dxva2_frames_init,
> > + .frames_uninit = dxva2_frames_uninit,
> > + .frames_get_buffer = dxva2_get_buffer,
> > + .transfer_get_formats = dxva2_transfer_get_formats,
> > + .transfer_data_to = dxva2_transfer_data,
> > + .transfer_data_from = dxva2_transfer_data,
> > +
> > + .pix_fmts = (const enum AVPixelFormat[]){
> > AV_PIX_FMT_DXVA2_VLD, AV_PIX_FMT_NONE },
> > +};
> > diff --git a/libavutil/hwcontext_dxva2.h b/libavutil/hwcontext_dxva2.h
> > new file mode 100644
> > index 0000000..2290c26
> > --- /dev/null
> > +++ b/libavutil/hwcontext_dxva2.h
> > @@ -0,0 +1,72 @@
> > +/*
> > + * This file is part of Libav.
> > + *
> > + * Libav 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.
> > + *
> > + * Libav 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 Libav; if not, write to the Free Software
> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> > 02110-1301 USA
> > + */
> > +
> > +
> > +#ifndef AVUTIL_HWCONTEXT_DXVA2_H
> > +#define AVUTIL_HWCONTEXT_DXVA2_H
> > +
> > +/**
> > + * @file
> > + * An API-specific header for AV_HWDEVICE_TYPE_DXVA2.
> > + *
> > + * Only fixed-size pools are supported.
> > + *
> > + * For user-allocated pools, AVHWFramesContext.pool must return
> > AVBufferRefs
> > + * with the data pointer set to a pointer to IDirect3DSurface9.
> > + */
> > +
> > +#include <d3d9.h>
> > +#include <dxva2api.h>
> > +
> > +/**
> > + * This struct is allocated as AVHWDeviceContext.hwctx
> > + */
> > +typedef struct AVDXVA2DeviceContext {
> > + IDirect3DDeviceManager9 *devmgr;
> > +} AVDXVA2DeviceContext;
> > +
> > +/**
> > + * This struct is allocated as AVHWFramesContext.hwctx
> > + */
> > +typedef struct AVDXVA2FramesContext {
> > + /**
> > + * The surface type (e.g. DXVA2_VideoProcessorRenderTarget or
> > + * DXVA2_VideoDecoderRenderTarget). Must be set by the caller.
> > + */
> > + DWORD surface_type;
> > +
> > + /**
> > + * The surface pool. When an external pool is not provided by the
> > caller,
> > + * this will be managed (allocated and filled on init, freed on
> > uninit) by
> > + * libavutil.
> > + */
> > + IDirect3DSurface9 **surfaces;
> > + int nb_surfaces;
> > +
> > + /**
> > + * Certain drivers require the decoder to be destroyed before the
> > surfaces.
> > + * To allow internally managed pools to work properly in such cases,
> > this
> > + * field is provided.
> > + *
> > + * If it is non-NULL, libavutil will call
> > IDirectXVideoDecoder_Release() on
> > + * it just before the internal surface pool is freed.
> > + */
> > + IDirectXVideoDecoder *decoder_to_release;
> > +} AVDXVA2FramesContext;
>
> That's going to behave pretty badly with all those dynamically loaded
> DLLs. If you unload a DLL while a frame is still referenced, everything
> will crash.
I don't understand what you mean here. What DLLs are getting unloaded
where?
--
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel