Ejemplo n.º 1
0
Archivo: d3d11va.c Proyecto: DZW314/mpv
static struct mp_image *d3d11va_new_ref(ID3D11VideoDecoderOutputView *view,
                                        int w, int h)
{
    if (!view)
        return NULL;
    struct d3d11va_surface *surface = talloc_zero(NULL, struct d3d11va_surface);

    surface->surface = view;
    ID3D11VideoDecoderOutputView_AddRef(surface->surface);
    ID3D11VideoDecoderOutputView_GetResource(
        surface->surface, (ID3D11Resource **)&surface->texture);

    D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC surface_desc;
    ID3D11VideoDecoderOutputView_GetDesc(surface->surface, &surface_desc);
    surface->subindex = surface_desc.Texture2D.ArraySlice;

    struct mp_image *mpi =
        mp_image_new_custom_ref(NULL, surface, d3d11va_release_img);
    if (!mpi)
        abort();

    mp_image_setfmt(mpi, IMGFMT_D3D11VA);
    mp_image_set_size(mpi, w, h);
    mpi->planes[0] = NULL;
    mpi->planes[1] = (void *)surface->texture;
    mpi->planes[2] = (void *)(intptr_t)surface->subindex;
    mpi->planes[3] = (void *)surface->surface;

    return mpi;
}
Ejemplo n.º 2
0
static int Extract(vlc_va_t *va, picture_t *output, uint8_t *data)
{
    vlc_va_sys_t *sys = va->sys;
    ID3D11VideoDecoderOutputView *src = (ID3D11VideoDecoderOutputView*)(uintptr_t)data;
    vlc_va_surface_t *surface = output->context;

    if (output->format.i_chroma == VLC_CODEC_D3D11_OPAQUE)
    {
        /* copy decoder slice to surface */
        D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
        picture_sys_t *p_sys_out = output->p_sys;
        picture_sys_t *p_sys_in = surface->p_pic->p_sys;

        assert(p_sys_out->texture != NULL);
        assert(p_sys_in->decoder == src);

        ID3D11VideoDecoderOutputView_GetDesc( src, &viewDesc );
        ID3D11DeviceContext_CopySubresourceRegion(sys->d3dctx, (ID3D11Resource*) p_sys_out->texture,
                                                  0, 0, 0, 0,
                                                  (ID3D11Resource*) p_sys_in->texture,
                                                  viewDesc.Texture2D.ArraySlice,
                                                  NULL);
    }
    else if (output->format.i_chroma == VLC_CODEC_YV12) {
        va->sys->filter->owner.sys = output;
        picture_Hold( surface->p_pic );
        va->sys->filter->pf_video_filter( va->sys->filter, surface->p_pic );
    } else {
        msg_Err(va, "Unsupported output picture format %08X", output->format.i_chroma );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
Archivo: dxva2.c Proyecto: tmm1/FFmpeg
unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx,
                                    const AVDXVAContext *ctx,
                                    const AVFrame *frame)
{
    void *surface = ff_dxva2_get_surface(frame);
    unsigned i;

    for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++)
#if CONFIG_D3D11VA
        if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD && ctx->d3d11va.surface[i] == surface)
        {
            D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
            ID3D11VideoDecoderOutputView_GetDesc(ctx->d3d11va.surface[i], &viewDesc);
            return viewDesc.Texture2D.ArraySlice;
        }
#endif
#if CONFIG_DXVA2
        if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && ctx->dxva2.surface[i] == surface)
            return i;
#endif

    assert(0);
    return 0;
}