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_linesize[4], dst_linesize[4]; for (i = 0; i < 4; i++) { dst_linesize[i] = dst->linesize[i]; src_linesize[i] = map->linesize[i]; } av_image_copy_uc_from(dst->data, dst_linesize, map->data, src_linesize, ctx->sw_format, src->width, src->height); } else { av_image_copy(map->data, map->linesize, src->data, src->linesize, ctx->sw_format, src->width, src->height); } fail: av_frame_free(&map); return ret; }
static int dxva2_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src) { AVFrame *map; ptrdiff_t src_linesize[4], dst_linesize[4]; int ret, i; if (dst->format != ctx->sw_format) return AVERROR(ENOSYS); map = av_frame_alloc(); if (!map) return AVERROR(ENOMEM); map->format = dst->format; ret = dxva2_map_frame(ctx, map, src, AV_HWFRAME_MAP_READ); if (ret < 0) goto fail; for (i = 0; i < 4; i++) { dst_linesize[i] = dst->linesize[i]; src_linesize[i] = map->linesize[i]; } av_image_copy_uc_from(dst->data, dst_linesize, map->data, src_linesize, ctx->sw_format, src->width, src->height); fail: av_frame_free(&map); return ret; }
static int dxva2_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src) { IDirect3DSurface9 *surface; D3DSURFACE_DESC surfaceDesc; D3DLOCKED_RECT LockedRect; HRESULT hr; 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]); 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, download ? 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; av_image_fill_pointers(surf_data, ctx->sw_format, surfaceDesc.Height, (uint8_t*)LockedRect.pBits, surf_linesize); if (download) { ptrdiff_t src_linesize1[4], dst_linesize1[4]; for (i = 0; i < 4; i++) { dst_linesize1[i] = dst->linesize[i]; src_linesize1[i] = surf_linesize[i]; } av_image_copy_uc_from(dst->data, dst_linesize1, surf_data, src_linesize1, ctx->sw_format, src->width, src->height); } else { av_image_copy(surf_data, surf_linesize, src->data, src->linesize, ctx->sw_format, src->width, src->height); } IDirect3DSurface9_UnlockRect(surface); return 0; }