Exemplo n.º 1
0
VideoFormat::PixelFormat pixelFormatFromFourcc(int format)
{
    const d3d_format_t *fmt = D3dFindFormat(format);
    if (fmt)
        return fmt->pixfmt;
    return VideoFormat::Format_Invalid;
}
Exemplo n.º 2
0
// hwaccel_context
bool VideoDecoderDXVAPrivate::setup(void **hwctx, AVPixelFormat *chroma, int w, int h)
{
    if (w <= 0 || h <= 0)
        return false;
    if (!decoder || ((width != w || height != h) &&
            (surface_width != FFALIGN(w, 16) || surface_height != FFALIGN(h, 16))//)
        )) {
        DxDestroyVideoConversion();
        DxDestroyVideoDecoder();
        *hwctx = NULL;
        *chroma = QTAV_PIX_FMT_C(NONE);
        /* FIXME transmit a video_format_t by VaSetup directly */
        if (!DxCreateVideoDecoder(codec_ctx->codec_id, w, h))
            return false;
        hw.decoder = decoder;
        hw.cfg = &cfg;
        hw.surface_count = surface_count;
        hw.surface = hw_surfaces;
        memset(hw_surfaces, 0, sizeof(hw_surfaces));
        for (unsigned i = 0; i < surface_count; i++)
            hw.surface[i] = surfaces[i].d3d;
        DxCreateVideoConversion();
    }
    *hwctx = &hw;
    const d3d_format_t *outfmt = D3dFindFormat(output);
    *chroma = outfmt ? outfmt->codec : QTAV_PIX_FMT_C(NONE);
    return true;
}
Exemplo n.º 3
0
VideoFrame VideoDecoderDXVA::frame()
{
    DPTR_D(VideoDecoderDXVA);
    if (!d.frame->opaque || !d.frame->data[0])
        return VideoFrame();
    if (d.width <= 0 || d.height <= 0 || !d.codec_ctx)
        return VideoFrame();

    class ScopedD3DLock {
    public:
        ScopedD3DLock(IDirect3DSurface9* d3d, D3DLOCKED_RECT *rect)
            : mpD3D(d3d)
        {
            if (FAILED(mpD3D->LockRect(rect, NULL, D3DLOCK_READONLY))) {
                qWarning("Failed to lock surface");
                mpD3D = 0;
            }
        }
        ~ScopedD3DLock() {
            if (mpD3D)
                mpD3D->UnlockRect();
        }
    private:
        IDirect3DSurface9 *mpD3D;
    };

    IDirect3DSurface9 *d3d = (IDirect3DSurface9*)(uintptr_t)d.frame->data[3];
    //picth >= desc.Width
    //D3DSURFACE_DESC desc;
    //d3d->GetDesc(&desc);
    D3DLOCKED_RECT lock;
    ScopedD3DLock(d3d, &lock);
    if (lock.Pitch == 0) {
        return VideoFrame();
    }

    const VideoFormat fmt = VideoFormat((int)D3dFindFormat(d.render)->avpixfmt);
    if (!fmt.isValid()) {
        qWarning("unsupported dxva pixel format: %#x", d.render);
        return VideoFrame();
    }
    //YV12 need swap, not imc3?
    // imc3 U V pitch == Y pitch, but half of the U/V plane is space. we convert to yuv420p here
    // nv12 bpp(1)==1
    // 3rd plane is not used for nv12
    int pitch[3] = { lock.Pitch, 0, 0}; //compute chroma later
    uint8_t *src[] = { (uint8_t*)lock.pBits, 0, 0}; //compute chroma later
    const bool swap_uv = d.render ==  MAKEFOURCC('I','M','C','3');
    return copyToFrame(fmt, d.surface_height, src, pitch, swap_uv);
}
Exemplo n.º 4
0
Arquivo: dxva2.c Projeto: tguillem/vlc
static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *fmt)
{
    VLC_UNUSED(fmt);
    int err = VLC_EGENERIC;
    UINT      output_count = 0;
    D3DFORMAT *output_list = NULL;
    if (FAILED(IDirectXVideoDecoderService_GetDecoderRenderTargets(va->sys->dx_sys.d3ddec,
                                                                   input,
                                                                   &output_count,
                                                                   &output_list))) {
        msg_Err(va, "IDirectXVideoDecoderService_GetDecoderRenderTargets failed");
        return VLC_EGENERIC;
    }

    for (unsigned j = 0; j < output_count; j++) {
        const D3DFORMAT f = output_list[j];
        const d3d_format_t *format = D3dFindFormat(f);
        if (format) {
            msg_Dbg(va, "%s is supported for output", format->name);
        } else {
            msg_Dbg(va, "%d is supported for output (%4.4s)", f, (const char*)&f);
        }
    }

    /* */
    for (unsigned pass = 0; pass < 2 && err != VLC_SUCCESS; ++pass)
    {
        for (unsigned j = 0; d3d_formats[j].name; j++) {
            const d3d_format_t *format = &d3d_formats[j];

            /* */
            bool is_supported = false;
            for (unsigned k = 0; !is_supported && k < output_count; k++) {
                is_supported = format->format == output_list[k];
            }
            if (!is_supported)
                continue;
            if (pass == 0 && format->format != va->sys->render)
                continue;

            /* We have our solution */
            msg_Dbg(va, "Using decoder output '%s'", format->name);
            va->sys->render = format->format;
            err = VLC_SUCCESS;
            break;
        }
    }
    CoTaskMemFree(output_list);
    return err;
}
Exemplo n.º 5
0
Arquivo: dxva2.c Projeto: 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;
}
Exemplo n.º 6
0
const d3d_format_t* VideoDecoderD3DPrivate::getFormat(const AVCodecContext *avctx, const QVector<GUID> &guids, GUID* selected) const
{
    foreach (const GUID& g, guids) {
        const dxva2_mode_t *mode = Dxva2FindMode(&g);
        if (mode) {
            qDebug("- '%s' is supported by hardware", mode->name);
        } else {
            qDebug("- Unknown GUID = %08X-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
                     (unsigned)g.Data1, g.Data2, g.Data3
                   , g.Data4[0], g.Data4[1]
                   , g.Data4[2], g.Data4[3], g.Data4[4], g.Data4[5], g.Data4[6], g.Data4[7]);
        }
    }
    /* Try all supported mode by our priority */
    const dxva2_mode_t *mode = dxva2_modes;
    for (; mode->name; ++mode) {
        if (!mode->codec || mode->codec != avctx->codec_id) {
            qDebug("codec does not match to %s: %s", avcodec_get_name(avctx->codec_id), avcodec_get_name((AVCodecID)mode->codec));
            continue;
        }
        qDebug("D3D found codec: %s. Check runtime support for the codec.", mode->name);
        bool is_supported = false;
        //TODO: find_if
        foreach (const GUID& g, guids) {
            if (IsEqualGUID(*mode->guid, g)) {
                is_supported = true;
                break;
            }
        }
        if (is_supported) {
            qDebug("Check profile support: %s", AVDecoderPrivate::getProfileName(avctx));
            is_supported = checkProfile(mode, avctx->profile);
        }
        if (!is_supported)
            continue;
        int dxfmt = fourccFor(mode->guid);
        if (!dxfmt)
            continue;
        if (selected)
            *selected = *mode->guid;
        return D3dFindFormat(dxfmt);
    }
    return NULL;
}
Exemplo n.º 7
0
int getSupportedFourcc(int *formats, UINT nb_formats)
{
    for (const int *f = formats; f < &formats[nb_formats]; ++f) {
        const d3d_format_t *format = D3dFindFormat(*f);
        if (format) {
            qDebug("%s is supported for output", format->name);
        } else {
            qDebug("%d is supported for output (%4.4s)", *f, (const char*)f);
        }
    }
    for (const d3d_format_t *format = d3d_formats; format->name; ++format) {
        bool is_supported = false;
        for (unsigned k = 0; !is_supported && k < nb_formats; k++) {
            if (format->fourcc == formats[k])
                return format->fourcc;
        }
    }
    return 0;
}
Exemplo n.º 8
0
static int Setup(vlc_va_t *va, void **hw, vlc_fourcc_t *chroma,
                 int width, int height)
{
    vlc_va_sys_t *sys = va->sys;

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

    /* */
    DxDestroyVideoConversion(sys);
    DxDestroyVideoDecoder(sys);

    *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, sys->codec_id, &fmt))
        return VLC_EGENERIC;
    /* */
    sys->hw.decoder = sys->decoder;
    sys->hw.cfg = &sys->cfg;
    sys->hw.surface_count = sys->surface_count;
    sys->hw.surface = sys->hw_surface;

    /* */
    DxCreateVideoConversion(sys);

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

    return VLC_SUCCESS;
}
Exemplo n.º 9
0
/**
 * Find the best suited decoder mode GUID and render format.
 */
static int DxFindVideoServiceConversion(vlc_va_dxva2_t *va, GUID *input, D3DFORMAT *output)
{
    /* Retreive supported modes from the decoder service */
    UINT input_count = 0;
    GUID *input_list = NULL;
    if (FAILED(IDirectXVideoDecoderService_GetDecoderDeviceGuids(va->vs,
                                                                 &input_count,
                                                                 &input_list))) {
        msg_Err(va->log, "IDirectXVideoDecoderService_GetDecoderDeviceGuids failed");
        return VLC_EGENERIC;
    }
    for (unsigned i = 0; i < input_count; i++) {
        const GUID *g = &input_list[i];
        const dxva2_mode_t *mode = Dxva2FindMode(g);
        if (mode) {
            msg_Dbg(va->log, "- '%s' is supported by hardware", mode->name);
        } else {
            msg_Warn(va->log, "- Unknown GUID = %08X-%04x-%04x-XXXX",
                     (unsigned)g->Data1, g->Data2, g->Data3);
        }
    }

    /* Try all supported mode by our priority */
    for (unsigned i = 0; dxva2_modes[i].name; i++) {
        const dxva2_mode_t *mode = &dxva2_modes[i];
        if (!mode->codec || mode->codec != va->codec_id)
            continue;

        /* */
        bool is_suported = false;
        for (const GUID *g = &input_list[0]; !is_suported && g < &input_list[input_count]; g++) {
            is_suported = IsEqualGUID(mode->guid, g);
        }
        if (!is_suported)
            continue;

        /* */
        msg_Dbg(va->log, "Trying to use '%s' as input", mode->name);
        UINT      output_count = 0;
        D3DFORMAT *output_list = NULL;
        if (FAILED(IDirectXVideoDecoderService_GetDecoderRenderTargets(va->vs, mode->guid,
                                                                       &output_count,
                                                                       &output_list))) {
            msg_Err(va->log, "IDirectXVideoDecoderService_GetDecoderRenderTargets failed");
            continue;
        }
        for (unsigned j = 0; j < output_count; j++) {
            const D3DFORMAT f = output_list[j];
            const d3d_format_t *format = D3dFindFormat(f);
            if (format) {
                msg_Dbg(va->log, "%s is supported for output", format->name);
            } else {
                msg_Dbg(va->log, "%d is supported for output (%4.4s)", f, (const char*)&f);
            }
        }

        /* */
        for (unsigned j = 0; d3d_formats[j].name; j++) {
            const d3d_format_t *format = &d3d_formats[j];

            /* */
            bool is_suported = false;
            for (unsigned k = 0; !is_suported && k < output_count; k++) {
                is_suported = format->format == output_list[k];
            }
            if (!is_suported)
                continue;

            /* We have our solution */
            msg_Dbg(va->log, "Using '%s' to decode to '%s'", mode->name, format->name);
            *input  = *mode->guid;
            *output = format->format;
            CoTaskMemFree(output_list);
            CoTaskMemFree(input_list);
            return VLC_SUCCESS;
        }
        CoTaskMemFree(output_list);
    }
    CoTaskMemFree(input_list);
    return VLC_EGENERIC;
}
Exemplo n.º 10
0
/**
 * Find the best suited decoder mode GUID and render format.
 */
bool VideoDecoderDXVAPrivate::DxFindVideoServiceConversion(GUID *input, D3DFORMAT *output)
{
    /* Retreive supported modes from the decoder service */
    UINT input_count = 0;
    GUID *input_list = NULL;
    if (FAILED(vs->GetDecoderDeviceGuids(&input_count, &input_list))) {
        qWarning("IDirectXVideoDecoderService_GetDecoderDeviceGuids failed");
        return false;
    }
    for (unsigned i = 0; i < input_count; i++) {
        const GUID &g = input_list[i];
        const dxva2_mode_t *mode = Dxva2FindMode(&g);
        if (mode) {
            qDebug("- '%s' is supported by hardware", mode->name);
        } else {
            qWarning("- Unknown GUID = %08X-%04x-%04x-XXXX",
                     (unsigned)g.Data1, g.Data2, g.Data3);
        }
    }
    /* Try all supported mode by our priority */
    for (unsigned i = 0; dxva2_modes[i].name; i++) {
        const dxva2_mode_t *mode = &dxva2_modes[i];
        if (!mode->codec || mode->codec != codec_ctx->codec_id)
            continue;
        bool is_suported = false;
        for (unsigned count = 0; !is_suported && count < input_count; count++) {
            const GUID &g = input_list[count];
            is_suported = IsEqualGUID(*mode->guid, g); ///
        }
        if (!is_suported)
            continue;

        qDebug("Trying to use '%s' as input", mode->name);
        UINT      output_count = 0;
        D3DFORMAT *output_list = NULL;
        if (FAILED(vs->GetDecoderRenderTargets(*mode->guid, &output_count, &output_list))) {
            qWarning("IDirectXVideoDecoderService_GetDecoderRenderTargets failed");
            continue;
        }
        for (unsigned j = 0; j < output_count; j++) {
            const D3DFORMAT f = output_list[j];
            const d3d_format_t *format = D3dFindFormat(f);
            if (format) {
                qDebug("%s is supported for output", format->name);
            } else {
                qDebug("%d is supported for output (%4.4s)", f, (const char*)&f);
            }
        }

        for (unsigned j = 0; d3d_formats[j].name; j++) {
            const d3d_format_t *format = &d3d_formats[j];
            bool is_suported = false;
            for (unsigned k = 0; !is_suported && k < output_count; k++) {
                is_suported = format->format == output_list[k];
            }
            if (!is_suported)
                continue;

            /* We have our solution */
            qDebug("Using '%s' to decode to '%s'", mode->name, format->name);
            *input  = *mode->guid;
            *output = format->format;
            CoTaskMemFree(output_list);
            CoTaskMemFree(input_list);
            return true;
        }
        CoTaskMemFree(output_list);
    }
    CoTaskMemFree(input_list);
    return false;
}
Exemplo n.º 11
0
/**
 * Find the best suited decoder mode GUID and render format.
 */
bool VideoDecoderDXVAPrivate::DxFindVideoServiceConversion(GUID *input, D3DFORMAT *output)
{
    /* Retreive supported modes from the decoder service */
    UINT input_count = 0;
    GUID *input_list = NULL;
    DX_ENSURE_OK(vs->GetDecoderDeviceGuids(&input_count, &input_list), false);
    for (unsigned i = 0; i < input_count; i++) {
        const GUID &g = input_list[i];
        const dxva2_mode_t *mode = Dxva2FindMode(&g);
        if (mode) {
            qDebug("- '%s' is supported by hardware", mode->name);
        } else {
            qDebug("- Unknown GUID = %08X-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
                     (unsigned)g.Data1, g.Data2, g.Data3
                   , g.Data4[0], g.Data4[1]
                   , g.Data4[2], g.Data4[3], g.Data4[4], g.Data4[5], g.Data4[6], g.Data4[7]);
        }
    }
    /* Try all supported mode by our priority */
    const dxva2_mode_t *mode = dxva2_modes;
    for (; mode->name; ++mode) {
        if (!mode->codec || mode->codec != codec_ctx->codec_id) {
            qDebug("codec does not match to %s: %s", avcodec_get_name(codec_ctx->codec_id), avcodec_get_name((AVCodecID)mode->codec));
            continue;
        }
        qDebug("DXVA found codec: %s. Check runtime support for the codec.", mode->name);
        bool is_supported = false;
        for (const GUID *g = &input_list[0]; !is_supported && g < &input_list[input_count]; g++) {
            is_supported = IsEqualGUID(*mode->guid, *g);
        }
        if (is_supported) {
            qDebug("Check profile support: %s", AVDecoderPrivate::getProfileName(codec_ctx));
            is_supported = !mode->profiles || !mode->profiles[0] || codec_ctx->profile <= 0;
            if (!is_supported) {
                for (const int *profile = &mode->profiles[0]; *profile; ++profile) {
                    if (*profile == codec_ctx->profile) {
                        is_supported = true;
                        break;
                    }
                }
            }
        }
        if (!is_supported)
            continue;

        UINT output_count = 0;
        D3DFORMAT *output_list = NULL;
        if (FAILED(vs->GetDecoderRenderTargets(*mode->guid, &output_count, &output_list))) {
            qWarning("IDirectXVideoDecoderService_GetDecoderRenderTargets failed");
            continue;
        }
        qDebug("supprted output count: %d", output_count);
        for (const D3DFORMAT *f = output_list; f < &output_list[output_count]; ++f) {
            const d3d_format_t *format = D3dFindFormat(*f);
            if (format) {
                qDebug("%s is supported for output", format->name);
            } else {
                qDebug("%d is supported for output (%4.4s)", *f, (const char*)f);
            }
        }

        for (const d3d_format_t *format = d3d_formats; format->name; ++format) {
            bool is_supported = false;
            for (unsigned k = 0; !is_supported && k < output_count; k++) {
                is_supported = format->format == output_list[k];
            }
            if (!is_supported)
                continue;

            /* We have our solution */
            qDebug("Using '%s' to decode to '%s'", mode->name, format->name);
            *input  = *mode->guid;
            *output = format->format;
            CoTaskMemFree(output_list);
            CoTaskMemFree(input_list);
            return true;
        }
        CoTaskMemFree(output_list);
    }
    CoTaskMemFree(input_list);
    return false;
}
Exemplo n.º 12
0
/**
 * Find the best suited decoder mode GUID and render format.
 */
bool VideoDecoderDXVAPrivate::DxFindVideoServiceConversion(GUID *input, D3DFORMAT *output)
{
    /* Retreive supported modes from the decoder service */
    UINT input_count = 0;
    GUID *input_list = NULL;
    DX_ENSURE_OK(vs->GetDecoderDeviceGuids(&input_count, &input_list), false);
    for (unsigned i = 0; i < input_count; i++) {
        const GUID &g = input_list[i];
        const dxva2_mode_t *mode = Dxva2FindMode(&g);
        if (mode) {
            qDebug("- '%s' is supported by hardware", mode->name);
        } else {
            qDebug("- Unknown GUID = %08X-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
                     (unsigned)g.Data1, g.Data2, g.Data3
                   , g->Data4[0], g->Data4[1]
                   , g->Data4[2], g->Data4[3], g->Data4[4], g->Data4[5], g->Data4[6], g->Data4[7]);
        }
    }
    /* Try all supported mode by our priority */
    for (unsigned i = 0; dxva2_modes[i].name; i++) {
        const dxva2_mode_t *mode = &dxva2_modes[i];
        if (!mode->codec || mode->codec != codec_ctx->codec_id) {
            qDebug("codec does not match to %s: %s", avcodec_get_name(codec_ctx->codec_id), avcodec_get_name((AVCodecID)mode->codec));
            continue;
        }
        if (codec_ctx->profile == FF_PROFILE_HEVC_MAIN_10 && !IsEqualGUID(*mode->guid, DXVA_ModeHEVC_VLD_Main10)) {
            qDebug("profile (%s) does not match to HEVC 10-bit", mode->name);
            continue;
        }
        qDebug("DXVA found codec: %s. Check support for the codec.", mode->name);
        bool is_suported = false;
        for (unsigned count = 0; !is_suported && count < input_count; count++) {
            const GUID &g = input_list[count];
            is_suported = IsEqualGUID(*mode->guid, g); ///
        }
        if (!is_suported)
            continue;

        UINT output_count = 0;
        D3DFORMAT *output_list = NULL;
        if (FAILED(vs->GetDecoderRenderTargets(*mode->guid, &output_count, &output_list))) {
            qWarning("IDirectXVideoDecoderService_GetDecoderRenderTargets failed");
            continue;
        }
        qDebug("supprted output count: %d", output_count);
        for (unsigned j = 0; j < output_count; j++) {
            const D3DFORMAT f = output_list[j];
            const d3d_format_t *format = D3dFindFormat(f);
            if (format) {
                qDebug("%s is supported for output", format->name);
            } else {
                qDebug("%d is supported for output (%4.4s)", f, (const char*)&f);
            }
        }

        for (unsigned j = 0; d3d_formats[j].name; j++) {
            const d3d_format_t *format = &d3d_formats[j];
            bool is_suported = false;
            for (unsigned k = 0; !is_suported && k < output_count; k++) {
                is_suported = format->format == output_list[k];
            }
            if (!is_suported)
                continue;

            /* We have our solution */
            qDebug("Using '%s' to decode to '%s'", mode->name, format->name);
            *input  = *mode->guid;
            *output = format->format;
            CoTaskMemFree(output_list);
            CoTaskMemFree(input_list);
            return true;
        }
        CoTaskMemFree(output_list);
    }
    CoTaskMemFree(input_list);
    return false;
}