static struct mp_image *d3d11va_retrieve_image(struct lavc_ctx *s, struct mp_image *img) { HRESULT hr; struct priv *p = s->hwdec_priv; ID3D11Texture2D *staging = p->decoder->staging; if (img->imgfmt != IMGFMT_D3D11VA) return img; ID3D11Texture2D *texture = (void *)img->planes[1]; int subindex = (intptr_t)img->planes[2]; if (!texture) { MP_ERR(p, "Failed to get Direct3D texture and surface from mp_image\n"); return img; } D3D11_TEXTURE2D_DESC texture_desc; ID3D11Texture2D_GetDesc(texture, &texture_desc); if (texture_desc.Width < img->w || texture_desc.Height < img->h) { MP_ERR(p, "Direct3D11 texture smaller than mp_image dimensions\n"); return img; } // copy to the staging texture ID3D11DeviceContext_CopySubresourceRegion( p->device_ctx, (ID3D11Resource *)staging, 0, 0, 0, 0, (ID3D11Resource *)texture, subindex, NULL); struct mp_image *sw_img = mp_image_pool_get(p->sw_pool, p->decoder->mpfmt_decoded, texture_desc.Width, texture_desc.Height); if (!sw_img) { MP_ERR(p, "Failed to get %s surface from CPU pool\n", mp_imgfmt_to_name(p->decoder->mpfmt_decoded)); return img; } // copy staging texture to the cpu mp_image D3D11_MAPPED_SUBRESOURCE lock; hr = ID3D11DeviceContext_Map(p->device_ctx, (ID3D11Resource *)staging, 0, D3D11_MAP_READ, 0, &lock); if (FAILED(hr)) { MP_ERR(p, "Failed to map D3D11 surface: %s\n", mp_HRESULT_to_str(hr)); talloc_free(sw_img); return img; } copy_nv12(sw_img, lock.pData, lock.RowPitch, texture_desc.Height); ID3D11DeviceContext_Unmap(p->device_ctx, (ID3D11Resource *)staging, 0); mp_image_set_size(sw_img, img->w, img->h); mp_image_copy_attributes(sw_img, img); talloc_free(img); return sw_img; }
static struct mp_image *d3d11va_retrieve_image(struct lavc_ctx *s, struct mp_image *img) { HRESULT hr; struct priv *p = s->hwdec_priv; ID3D11Texture2D *staging = p->decoder->staging; ID3D11Texture2D *texture = d3d11_texture_in_mp_image(img); ID3D11VideoDecoderOutputView *surface = d3d11_surface_in_mp_image(img); if (!texture || !surface) { MP_ERR(p, "Failed to get Direct3D texture and surface from mp_image\n"); return img; } D3D11_TEXTURE2D_DESC texture_desc; ID3D11Texture2D_GetDesc(texture, &texture_desc); if (texture_desc.Width < img->w || texture_desc.Height < img->h) { MP_ERR(p, "Direct3D11 texture smaller than mp_image dimensions\n"); return img; } // copy to the staging texture D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC surface_desc; ID3D11VideoDecoderOutputView_GetDesc(surface, &surface_desc); ID3D11DeviceContext_CopySubresourceRegion( p->device_ctx, (ID3D11Resource *)staging, 0, 0, 0, 0, (ID3D11Resource *)texture, surface_desc.Texture2D.ArraySlice, NULL); struct mp_image *sw_img = mp_image_pool_get(p->sw_pool, p->decoder->mpfmt_decoded, texture_desc.Width, texture_desc.Height); if (!sw_img) { MP_ERR(p, "Failed to get %s surface from CPU pool\n", mp_imgfmt_to_name(p->decoder->mpfmt_decoded)); return img; } // copy staging texture to the cpu mp_image D3D11_MAPPED_SUBRESOURCE lock; hr = ID3D11DeviceContext_Map(p->device_ctx, (ID3D11Resource *)staging, 0, D3D11_MAP_READ, 0, &lock); if (FAILED(hr)) { MP_ERR(p, "Failed to map D3D11 surface: %s\n", mp_HRESULT_to_str(hr)); talloc_free(sw_img); return img; } copy_nv12(sw_img, lock.pData, lock.RowPitch, texture_desc.Height); ID3D11DeviceContext_Unmap(p->device_ctx, (ID3D11Resource *)staging, 0); mp_image_set_size(sw_img, img->w, img->h); mp_image_copy_attributes(sw_img, img); talloc_free(img); return sw_img; }
static void Upload_Texture_32(ID3D11Texture2D *tex, unsigned int *data, int datawidth, int dataheight, unsigned int flags) { int x, y; unsigned int *dest; // unsigned char swapbuf[4]; // unsigned char swapbuf2[4]; D3D11_MAPPED_SUBRESOURCE lock; D3D11_TEXTURE2D_DESC desc; if (!tex) return; desc.Width = 0; desc.Height = 0; ID3D11Texture2D_GetDesc(tex, &desc); #if 0 if (width == desc.Width && height == desc.Height) { ID3D11DeviceContext_UpdateSubresource(d3ddevctx, (ID3D11Resource*)tex, 0, NULL, data, width*4, width*height*4); return; } Con_Printf("Wrong size!\n"); return; #else if (FAILED(ID3D11DeviceContext_Map(d3ddevctx, (ID3D11Resource*)tex, 0, D3D11_MAP_WRITE_DISCARD, 0, &lock))) { Con_Printf("Dynamic texture update failed\n"); return; } if (datawidth == desc.Width && dataheight == desc.Height) { for (y = 0; y < dataheight; y++) { dest = (unsigned int *)((char *)lock.pData + lock.RowPitch*y); for (x = 0; x < datawidth; x++) { // *(unsigned int*)swapbuf2 = *(unsigned int*)swapbuf = data[x]; // swapbuf[0] = swapbuf2[2]; // swapbuf[2] = swapbuf2[0]; dest[x] = data[x];//*(unsigned int*)swapbuf; } data += datawidth; } } else { int x, y; int iny; unsigned int *row, *inrow; for (y = 0; y < desc.Height; y++) { row = (unsigned int*)((char *)lock.pData + lock.RowPitch*y); iny = (y * dataheight) / desc.Height; inrow = data + datawidth*iny; for (x = 0; x < desc.Width; x++) { //*(unsigned int*)swapbuf2 = *(unsigned int*)swapbuf = inrow[(x * width)/desc.Width]; //swapbuf[0] = swapbuf2[2]; //swapbuf[2] = swapbuf2[0]; row[x] = inrow[(x * datawidth)/desc.Width];//*(unsigned int*)swapbuf; } } } ID3D11DeviceContext_Unmap(d3ddevctx, (ID3D11Resource*)tex, 0); #endif }