[FFmpeg-cvslog] hwcontext_dxva2: frame mapping support
Anton Khirnov
git at videolan.org
Thu Mar 30 12:39:20 EEST 2017
ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Wed Oct 5 13:39:44 2016 +0200| [910973765417f06a4a9ccbd006e4df74c32ecb01] | committer: Anton Khirnov
hwcontext_dxva2: frame mapping support
Signed-off-by: Maxym Dmytrychenko <maxym.dmytrychenko at intel.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=910973765417f06a4a9ccbd006e4df74c32ecb01
---
libavutil/hwcontext_dxva2.c | 89 ++++++++++++++++++++++++++++++++++-----------
1 file changed, 68 insertions(+), 21 deletions(-)
diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c
index da89453..eb1bc46 100644
--- a/libavutil/hwcontext_dxva2.c
+++ b/libavutil/hwcontext_dxva2.c
@@ -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*)hwmap->source->data[3];
+ IDirect3DSurface9_UnlockRect(surface);
+}
+
+static int dxva2_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src,
+ int flags)
{
- IDirect3DSurface9 *surface;
+ 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;
+
+ 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;
- av_image_fill_pointers(surf_data, ctx->sw_format, surfaceDesc.Height,
- (uint8_t*)LockedRect.pBits, surf_linesize);
+ 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 },
};
More information about the ffmpeg-cvslog
mailing list