mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-27 21:40:34 +00:00
hwcontext_dxva2: frame mapping support
Signed-off-by: Maxym Dmytrychenko <maxym.dmytrychenko@intel.com>
This commit is contained in:
parent
fabfbfe571
commit
9109737654
@ -241,21 +241,22 @@ static int dxva2_transfer_get_formats(AVHWFramesContext *ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dxva2_transfer_data(AVHWFramesContext *ctx, AVFrame *dst,
|
||||
const AVFrame *src)
|
||||
static void dxva2_unmap_frame(AVHWFramesContext *ctx, HWMapDescriptor *hwmap)
|
||||
{
|
||||
IDirect3DSurface9 *surface;
|
||||
IDirect3DSurface9 *surface = (IDirect3DSurface9*)hwmap->source->data[3];
|
||||
IDirect3DSurface9_UnlockRect(surface);
|
||||
}
|
||||
|
||||
static int dxva2_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src,
|
||||
int flags)
|
||||
{
|
||||
IDirect3DSurface9 *surface = (IDirect3DSurface9*)src->data[3];
|
||||
D3DSURFACE_DESC surfaceDesc;
|
||||
D3DLOCKED_RECT LockedRect;
|
||||
HRESULT hr;
|
||||
int i, err, nb_planes;
|
||||
|
||||
uint8_t *surf_data[4] = { NULL };
|
||||
int surf_linesize[4] = { 0 };
|
||||
int i;
|
||||
|
||||
int download = !!src->hw_frames_ctx;
|
||||
|
||||
surface = (IDirect3DSurface9*)(download ? src->data[3] : dst->data[3]);
|
||||
nb_planes = av_pix_fmt_count_planes(dst->format);
|
||||
|
||||
hr = IDirect3DSurface9_GetDesc(surface, &surfaceDesc);
|
||||
if (FAILED(hr)) {
|
||||
@ -264,32 +265,77 @@ static int dxva2_transfer_data(AVHWFramesContext *ctx, AVFrame *dst,
|
||||
}
|
||||
|
||||
hr = IDirect3DSurface9_LockRect(surface, &LockedRect, NULL,
|
||||
download ? D3DLOCK_READONLY : D3DLOCK_DISCARD);
|
||||
flags & AV_HWFRAME_MAP_READ ? D3DLOCK_READONLY : D3DLOCK_DISCARD);
|
||||
if (FAILED(hr)) {
|
||||
av_log(ctx, AV_LOG_ERROR, "Unable to lock DXVA2 surface\n");
|
||||
return AVERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
for (i = 0; download ? dst->data[i] : src->data[i]; i++)
|
||||
surf_linesize[i] = LockedRect.Pitch;
|
||||
err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src,
|
||||
dxva2_unmap_frame, NULL);
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
|
||||
av_image_fill_pointers(surf_data, ctx->sw_format, surfaceDesc.Height,
|
||||
(uint8_t*)LockedRect.pBits, surf_linesize);
|
||||
for (i = 0; i < nb_planes; i++)
|
||||
dst->linesize[i] = LockedRect.Pitch;
|
||||
|
||||
av_image_fill_pointers(dst->data, dst->format, surfaceDesc.Height,
|
||||
(uint8_t*)LockedRect.pBits, dst->linesize);
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
IDirect3DSurface9_UnlockRect(surface);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int dxva2_transfer_data(AVHWFramesContext *ctx, AVFrame *dst,
|
||||
const AVFrame *src)
|
||||
{
|
||||
int download = !!src->hw_frames_ctx;
|
||||
|
||||
AVFrame *map;
|
||||
int ret, i;
|
||||
|
||||
map = av_frame_alloc();
|
||||
if (!map)
|
||||
return AVERROR(ENOMEM);
|
||||
map->format = dst->format;
|
||||
|
||||
ret = dxva2_map_frame(ctx, map, download ? src : dst,
|
||||
download ? AV_HWFRAME_MAP_READ : AV_HWFRAME_MAP_WRITE);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
if (download) {
|
||||
ptrdiff_t src_linesize1[4], dst_linesize1[4];
|
||||
ptrdiff_t src_linesize[4], dst_linesize[4];
|
||||
for (i = 0; i < 4; i++) {
|
||||
dst_linesize1[i] = dst->linesize[i];
|
||||
src_linesize1[i] = surf_linesize[i];
|
||||
dst_linesize[i] = dst->linesize[i];
|
||||
src_linesize[i] = map->linesize[i];
|
||||
}
|
||||
av_image_copy_uc_from(dst->data, dst_linesize1, surf_data, src_linesize1,
|
||||
av_image_copy_uc_from(dst->data, dst_linesize, map->data, src_linesize,
|
||||
ctx->sw_format, src->width, src->height);
|
||||
} else {
|
||||
av_image_copy(surf_data, surf_linesize, src->data, src->linesize,
|
||||
av_image_copy(map->data, map->linesize, src->data, src->linesize,
|
||||
ctx->sw_format, src->width, src->height);
|
||||
}
|
||||
|
||||
IDirect3DSurface9_UnlockRect(surface);
|
||||
fail:
|
||||
av_frame_free(&map);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dxva2_map_from(AVHWFramesContext *ctx,
|
||||
AVFrame *dst, const AVFrame *src, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = dxva2_map_frame(ctx, dst, src, flags);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = av_frame_copy_props(dst, src);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -428,6 +474,7 @@ const HWContextType ff_hwcontext_type_dxva2 = {
|
||||
.transfer_get_formats = dxva2_transfer_get_formats,
|
||||
.transfer_data_to = dxva2_transfer_data,
|
||||
.transfer_data_from = dxva2_transfer_data,
|
||||
.map_from = dxva2_map_from,
|
||||
|
||||
.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_DXVA2_VLD, AV_PIX_FMT_NONE },
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user