Beispiel #1
0
static void Release(vlc_va_t *external, AVFrame *ff)
{
    vlc_va_dxva2_t *va = vlc_va_dxva2_Get(external);
    LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)ff->data[3];

    for (unsigned i = 0; i < va->surface_count; i++) {
        vlc_va_surface_t *surface = &va->surface[i];

        if (surface->d3d == d3d)
            surface->refcount--;
    }
}
Beispiel #2
0
static void Close(vlc_va_t *external)
{
    vlc_va_dxva2_t *va = vlc_va_dxva2_Get(external);

    DxDestroyVideoConversion(va);
    DxDestroyVideoDecoder(va);
    DxDestroyVideoService(va);
    D3dDestroyDeviceManager(va);
    D3dDestroyDevice(va);

    if (va->hdxva2_dll)
        FreeLibrary(va->hdxva2_dll);
    if (va->hd3d9_dll)
        FreeLibrary(va->hd3d9_dll);

    free(external->description);
    free(va);
}
Beispiel #3
0
/* FIXME it is nearly common with VAAPI */
static int Get(vlc_va_t *external, AVFrame *ff)
{
    vlc_va_dxva2_t *va = vlc_va_dxva2_Get(external);

    /* Check the device */
    HRESULT hr = IDirect3DDeviceManager9_TestDevice(va->devmng, va->device);
    if (hr == DXVA2_E_NEW_VIDEO_DEVICE) {
        if (DxResetVideoDecoder(va))
            return VLC_EGENERIC;
    } else if (FAILED(hr)) {
        msg_Err(va->log, "IDirect3DDeviceManager9_TestDevice %u", (unsigned)hr);
        return VLC_EGENERIC;
    }

    /* Grab an unused surface, in case none are, try the oldest
     * XXX using the oldest is a workaround in case a problem happens with libavcodec */
    unsigned i, old;
    for (i = 0, old = 0; i < va->surface_count; i++) {
        vlc_va_surface_t *surface = &va->surface[i];

        if (!surface->refcount)
            break;

        if (surface->order < va->surface[old].order)
            old = i;
    }
    if (i >= va->surface_count)
        i = old;

    vlc_va_surface_t *surface = &va->surface[i];

    surface->refcount = 1;
    surface->order = va->surface_order++;

    /* */
    for (int i = 0; i < 4; i++) {
        ff->data[i] = NULL;
        ff->linesize[i] = 0;

        if (i == 0 || i == 3)
            ff->data[i] = (void*)surface->d3d;/* Yummie */
    }
    return VLC_SUCCESS;
}
Beispiel #4
0
Datei: dxva2.c Projekt: Tilka/vlc
static int Setup(vlc_va_t *external, void **hw, vlc_fourcc_t *chroma,
                 int width, int height)
{
    vlc_va_dxva2_t *va = vlc_va_dxva2_Get(external);

    if (va->width == width && va->height == height && va->decoder)
        goto ok;

    /* */
    DxDestroyVideoConversion(va);
    DxDestroyVideoDecoder(va);

    *hw = NULL;
    *chroma = 0;
    if (width <= 0 || height <= 0)
        return VLC_EGENERIC;

    /* FIXME transmit a video_format_t by VaSetup directly */
    video_format_t fmt;
    memset(&fmt, 0, sizeof(fmt));
    fmt.i_width = width;
    fmt.i_height = height;

    if (DxCreateVideoDecoder(va, va->codec_id, &fmt))
        return VLC_EGENERIC;
    /* */
    va->hw.decoder = va->decoder;
    va->hw.cfg = &va->cfg;
    va->hw.surface_count = va->surface_count;
    va->hw.surface = va->hw_surface;
    for (unsigned i = 0; i < va->surface_count; i++)
        va->hw.surface[i] = va->surface[i].d3d;

    /* */
    DxCreateVideoConversion(va);

    /* */
ok:
    *hw = &va->hw;
    const d3d_format_t *output = D3dFindFormat(va->output);
    *chroma = output->codec;

    return VLC_SUCCESS;
}
Beispiel #5
0
static int Extract(vlc_va_t *external, picture_t *picture, AVFrame *ff)
{
    vlc_va_dxva2_t *va = vlc_va_dxva2_Get(external);
    LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)ff->data[3];

    if (!va->surface_cache.buffer)
        return VLC_EGENERIC;

    /* */
    assert(va->output == MAKEFOURCC('Y','V','1','2'));

    /* */
    D3DLOCKED_RECT lock;
    if (FAILED(IDirect3DSurface9_LockRect(d3d, &lock, NULL, D3DLOCK_READONLY))) {
        msg_Err(va->log, "Failed to lock surface");
        return VLC_EGENERIC;
    }

    if (va->render == MAKEFOURCC('Y','V','1','2') ||
        va->render == MAKEFOURCC('I','M','C','3')) {
        bool imc3 = va->render == MAKEFOURCC('I','M','C','3');
        size_t chroma_pitch = imc3 ? lock.Pitch : (lock.Pitch / 2);

        size_t pitch[3] = {
            lock.Pitch,
            chroma_pitch,
            chroma_pitch,
        };

        uint8_t *plane[3] = {
            (uint8_t*)lock.pBits,
            (uint8_t*)lock.pBits + pitch[0] * va->surface_height,
            (uint8_t*)lock.pBits + pitch[0] * va->surface_height
                                 + pitch[1] * va->surface_height / 2,
        };

        if (imc3) {
            uint8_t *V = plane[1];
            plane[1] = plane[2];
            plane[2] = V;
        }
        CopyFromYv12(picture, plane, pitch,
                     va->width, va->height,
                     &va->surface_cache);
    } else {
        assert(va->render == MAKEFOURCC('N','V','1','2'));
        uint8_t *plane[2] = {
            lock.pBits,
            (uint8_t*)lock.pBits + lock.Pitch * va->surface_height
        };
        size_t  pitch[2] = {
            lock.Pitch,
            lock.Pitch,
        };
        CopyFromNv12(picture, plane, pitch,
                     va->width, va->height,
                     &va->surface_cache);
    }

    /* */
    IDirect3DSurface9_UnlockRect(d3d);
    return VLC_SUCCESS;
}