On Mon, 8 May 2017 22:59:11 +0100 Mark Thompson <[email protected]> wrote:
> On 04/05/17 07:44, wm4 wrote: > > To be used with the new d3d11 hwaccel decode API. > > > > With the new hwaccel API, we don't want surfaces to depend on the > > decoder (other than the required dimension and format). The old D3D11VA > > pixfmt uses ID3D11VideoDecoderOutputView pointers, which include the > > decoder configuration, and thus is incompatible with the new hwaccel > > API. This patch introduces AV_PIX_FMT_D3D11, which uses ID3D11Texture2D > > and an index. It's simpler and compatible with the new hwaccel API. > > > > The introduced hwcontext supports only the new pixfmt. > > > > Significantly based on work by Steve Lhomme <[email protected]>, but with > > heavy changes/rewrites. > > --- > > Somewhat sketchy: if initial_pool_size is set, the pool is assumed to > > be static. > > --- Any comments on that? > > +static int d3d11va_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, > > + const AVFrame *src) > > +{ > > + AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx; > > + D3D11VAFramesContext *s = ctx->internal->priv; > > + int download = !!src->hw_frames_ctx; > > This isn't correct - src could have hw_frames_ctx set as a mapped frame while > we are really uploading to dst. I don't think you can write this with only > one function. > > (Not sure there is any case where you would ever want to do that, though.) OK I guess. > > + const AVFrame *frame = download ? src : dst; > > + // (The interface types are compatible.) > > + ID3D11Resource *texture = (ID3D11Resource *)(ID3D11Texture2D > > *)frame->data[0]; > > + int index = (intptr_t)frame->data[1]; > > + ID3D11Resource *staging = (ID3D11Resource *)s->staging_texture; > > + int w = FFMIN(dst->width, src->width); > > + int h = FFMIN(dst->height, src->height); > > + uint8_t *map_data[4]; > > + int map_linesize[4]; > > + D3D11_TEXTURE2D_DESC desc; > > + D3D11_MAPPED_SUBRESOURCE map; > > + HRESULT hr; > > + > > + device_hwctx->lock(device_hwctx->lock_ctx); > > + > > + ID3D11Texture2D_GetDesc(s->staging_texture, &desc); > > + > > + if (download) { > > + > > ID3D11DeviceContext_CopySubresourceRegion(device_hwctx->device_context, > > + staging, 0, 0, 0, 0, > > + texture, index, NULL); > > + > > + hr = ID3D11DeviceContext_Map(device_hwctx->device_context, > > + staging, 0, D3D11_MAP_READ, 0, &map); > > + if (FAILED(hr)) > > + goto map_failed; > > + > > + fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map); > > + > > + av_image_copy(dst->data, dst->linesize, map_data, map_linesize, > > + ctx->sw_format, w, h); > > Is the staging texture somehow magic such that it isn't going to be uncached > memory or anything tricky like that? Yes, I'm fairly sure it simply lives in CPU memory, and CopySubresourceRegion() will access the actual video memory. This is also why d3d11 with copy back is slower than dxva2, apparently. > > + > > + ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, > > 0); > > + } else { > > + hr = ID3D11DeviceContext_Map(device_hwctx->device_context, > > + staging, 0, D3D11_MAP_WRITE, 0, &map); > > + if (FAILED(hr)) > > + goto map_failed; > > + > > + fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map); > > + > > + av_image_copy(map_data, map_linesize, src->data, src->linesize, > > + ctx->sw_format, w, h); > > + > > + ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, > > 0); > > + > > + > > ID3D11DeviceContext_CopySubresourceRegion(device_hwctx->device_context, > > + texture, index, 0, 0, 0, > > + staging, 0, NULL); > > + } > > + > > + device_hwctx->unlock(device_hwctx->lock_ctx); > > + return 0; > > + > > +map_failed: > > + av_log(ctx, AV_LOG_ERROR, "Unable to lock D3D11VA surface (%lx)\n", > > (long)hr); > > + device_hwctx->unlock(device_hwctx->lock_ctx); > > + return AVERROR_UNKNOWN; > > +} > > Seems like it would be nicer to implement map and use it rather than putting > it multiple times inside this function. Maybe. I'm unsure about the mapping semantics. Will look at it again. > > + AV_PIX_FMT_D3D11, ///< HW decoding through Direct3D11 via new API, > > Picture.data[0] contains a ID3D11Texture2D pointer, and data[1] contains > > the texture array index of the frame as intptr_t if the ID3D11Texture2D is > > an array texture (or 0 if it's a normal texture) > > The old format was specifically for decoding, but the new one is more general > than that. OK. Well, someone new to the API who's trying to figure out which format to use is going to be confused, so mentioning the new decode API might help. _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
