Beispiel #1
0
VaApi::VaApi() {
	init = true;
	auto xdpy = QX11Info::display();
	VADisplay display = m_display = vaGetDisplayGLX(xdpy);
	if (!check(display ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_UNIMPLEMENTED, "Cannot create VADisplay."))
		return;
	int major, minor;
	if (!check(vaInitialize(m_display, &major, &minor), "Cannot initialize VA-API."))
		return;
	auto size = vaMaxNumProfiles(display);
	m_profiles.resize(size);
	if (!check(vaQueryConfigProfiles(display, m_profiles.data(), &size), "No available profiles."))
		return;
	m_profiles.resize(size);

	for (auto profile : m_profiles) {
		int size = vaMaxNumEntrypoints(display);
        QVector<VAEntrypoint> entries(size);
		if (!isSuccess(vaQueryConfigEntrypoints(display, profile, entries.data(), &size)))
			continue;
		entries.resize(size);
		m_entries.insert(profile, entries);
	}

	initCodecs();
#ifdef USE_VAVPP
	initFilters();
#endif
	_Debug("VA-API is initialized.");
	ok = true;
}
Beispiel #2
0
static bool
IsEntrypointAvailable(VADisplay dpy, VAProfile i_profile,
                      VAEntrypoint entrypoint)
{
    VAEntrypoint *      entrypoints;
    int                 num_entrypoints = vaMaxNumEntrypoints(dpy);
    bool                ret = false;

    if (num_entrypoints <= 0)
        return false;
    entrypoints = vlc_alloc(num_entrypoints, sizeof(VAEntrypoint));

    if (!entrypoints)
        return false;

    VAStatus status =
        vaQueryConfigEntrypoints(dpy, i_profile, entrypoints, &num_entrypoints);
    if (status != VA_STATUS_SUCCESS)
        goto error;

    for (int i = 0; i < num_entrypoints; ++i)
        if (entrypoint == entrypoints[i])
        {
            ret = true;
            break;
        }

error:
    free(entrypoints);
    return ret;
}
Beispiel #3
0
static int has_entrypoint(VAAPIContext *vaapi, VAProfile profile, VAEntrypoint entrypoint)
{
    VAStatus status;
    int i;

    if (!vaapi->entrypoints || vaapi->n_entrypoints == 0) {
        vaapi->entrypoints = calloc(vaMaxNumEntrypoints(vaapi->display), sizeof(vaapi->entrypoints[0]));

        status = vaQueryConfigEntrypoints(vaapi->display, profile,
                                          vaapi->entrypoints,
                                          &vaapi->n_entrypoints);
        if (!vaapi_check_status(status, "vaQueryConfigEntrypoints()"))
            return 0;

        D(bug("%d entrypoints available for %s\n", vaapi->n_entrypoints,
              string_of_VAProfile(profile)));
        for (i = 0; i < vaapi->n_entrypoints; i++)
            D(bug("  %s\n", string_of_VAEntrypoint(vaapi->entrypoints[i])));
    }

    for (i = 0; i < vaapi->n_entrypoints; i++) {
        if (vaapi->entrypoints[i] == entrypoint)
            return 1;
    }
    return 0;
}
Beispiel #4
0
bool VAAPIContext::InitProfiles(void)
{
    if (!(codec_is_vaapi_hw(m_codec)) || !m_ctx.display)
        return false;

    MythXLocker locker(m_display->m_x_disp);
    int max_profiles, max_entrypoints;
    VAProfile profile_wanted = preferredProfile(m_codec);
    if (profile_wanted == VAProfileMPEG2Simple)
    {
        LOG(VB_PLAYBACK, LOG_ERR, LOC + "Codec is not supported.");
        return false;
    }

    VAProfile profile_found  = VAProfileMPEG2Simple; // unsupported value
    VAEntrypoint entry_found = VAEntrypointEncSlice; // unsupported value

    max_profiles          = vaMaxNumProfiles(m_ctx.display);
    max_entrypoints       = vaMaxNumEntrypoints(m_ctx.display);
    VAProfile *profiles   = new VAProfile[max_profiles];
    VAEntrypoint *entries = new VAEntrypoint[max_entrypoints];

    static bool debugged = false;
    if (profiles && entries)
    {
        INIT_ST;
        int act_profiles, act_entries;
        va_status = vaQueryConfigProfiles(m_ctx.display,
                                          profiles,
                                         &act_profiles);
        CHECK_ST;
        if (ok && act_profiles > 0)
        {
            for (int i = 0; i < act_profiles; i++)
            {
                va_status = vaQueryConfigEntrypoints(m_ctx.display,
                                                     profiles[i],
                                                     entries,
                                                    &act_entries);
                if (va_status == VA_STATUS_SUCCESS && act_entries > 0)
                {
                    if (profiles[i] == profile_wanted)
                    {
                        profile_found = profile_wanted;
                        for (int j = 0; j < act_entries; j++)
                            if (entries[j] < entry_found)
                                entry_found = entries[j];
                    }

                    if (!debugged)
                    {
                        QString entrylist = "Entrypoints: ";
                        for (int j = 0; j < act_entries; j++)
                            entrylist += entryToString(entries[j]);
                        LOG(VB_GENERAL, LOG_INFO, LOC +
                            QString("Profile: %1 %2")
                                .arg(profileToString(profiles[i]))
                                .arg(entrylist));
                    }
                }
            }
        }
        debugged = true;
    }
    delete [] profiles;
    delete [] entries;

    LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Desired profile for '%1': %2")
        .arg(toString(m_codec)).arg(profileToString(profile_wanted)));
    LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Found profile %1 with entry %2")
        .arg(profileToString(profile_found)).arg(entryToString(entry_found)));

    if (profile_wanted != profile_found)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to find supported profile.");
        return false;
    }

    if (entry_found > VAEntrypointVLD)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to find suitable entry point.");
        return false;
    }

    m_vaProfile = profile_wanted;
    m_vaEntrypoint = entry_found;
    if (VAEntrypointVLD == m_vaEntrypoint)
        m_pix_fmt = PIX_FMT_VAAPI_VLD;
    return true;
}
Beispiel #5
0
static av_cold int vaapi_encode_check_config(AVCodecContext *avctx)
{
    VAAPIEncodeContext *ctx = avctx->priv_data;
    VAStatus vas;
    int i, n, err;
    VAProfile    *profiles    = NULL;
    VAEntrypoint *entrypoints = NULL;
    VAConfigAttrib attr[] = {
        { VAConfigAttribRateControl     },
        { VAConfigAttribEncMaxRefFrames },
    };

    n = vaMaxNumProfiles(ctx->hwctx->display);
    profiles = av_malloc_array(n, sizeof(VAProfile));
    if (!profiles) {
        err = AVERROR(ENOMEM);
        goto fail;
    }
    vas = vaQueryConfigProfiles(ctx->hwctx->display, profiles, &n);
    if (vas != VA_STATUS_SUCCESS) {
        av_log(ctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n",
               vas, vaErrorStr(vas));
        err = AVERROR(ENOSYS);
        goto fail;
    }
    for (i = 0; i < n; i++) {
        if (profiles[i] == ctx->va_profile)
            break;
    }
    if (i >= n) {
        av_log(ctx, AV_LOG_ERROR, "Encoding profile not found (%d).\n",
               ctx->va_profile);
        err = AVERROR(ENOSYS);
        goto fail;
    }

    n = vaMaxNumEntrypoints(ctx->hwctx->display);
    entrypoints = av_malloc_array(n, sizeof(VAEntrypoint));
    if (!entrypoints) {
        err = AVERROR(ENOMEM);
        goto fail;
    }
    vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile,
                                   entrypoints, &n);
    if (vas != VA_STATUS_SUCCESS) {
        av_log(ctx, AV_LOG_ERROR, "Failed to query entrypoints for "
               "profile %u: %d (%s).\n", ctx->va_profile,
               vas, vaErrorStr(vas));
        err = AVERROR(ENOSYS);
        goto fail;
    }
    for (i = 0; i < n; i++) {
        if (entrypoints[i] == ctx->va_entrypoint)
            break;
    }
    if (i >= n) {
        av_log(ctx, AV_LOG_ERROR, "Encoding entrypoint not found "
               "(%d / %d).\n", ctx->va_profile, ctx->va_entrypoint);
        err = AVERROR(ENOSYS);
        goto fail;
    }

    vas = vaGetConfigAttributes(ctx->hwctx->display,
                                ctx->va_profile, ctx->va_entrypoint,
                                attr, FF_ARRAY_ELEMS(attr));
    if (vas != VA_STATUS_SUCCESS) {
        av_log(avctx, AV_LOG_ERROR, "Failed to fetch config "
               "attributes: %d (%s).\n", vas, vaErrorStr(vas));
        return AVERROR(EINVAL);
    }

    for (i = 0; i < FF_ARRAY_ELEMS(attr); i++) {
        if (attr[i].value == VA_ATTRIB_NOT_SUPPORTED) {
            // Unfortunately we have to treat this as "don't know" and hope
            // for the best, because the Intel MJPEG encoder returns this
            // for all the interesting attributes.
            continue;
        }
        switch (attr[i].type) {
        case VAConfigAttribRateControl:
            if (!(ctx->va_rc_mode & attr[i].value)) {
                av_log(avctx, AV_LOG_ERROR, "Rate control mode is not "
                       "supported: %x\n", attr[i].value);
                err = AVERROR(EINVAL);
                goto fail;
            }
            break;
        case VAConfigAttribEncMaxRefFrames:
        {
            unsigned int ref_l0 = attr[i].value & 0xffff;
            unsigned int ref_l1 = (attr[i].value >> 16) & 0xffff;

            if (avctx->gop_size > 1 && ref_l0 < 1) {
                av_log(avctx, AV_LOG_ERROR, "P frames are not "
                       "supported (%x).\n", attr[i].value);
                err = AVERROR(EINVAL);
                goto fail;
            }
            if (avctx->max_b_frames > 0 && ref_l1 < 1) {
                av_log(avctx, AV_LOG_ERROR, "B frames are not "
                       "supported (%x).\n", attr[i].value);
                err = AVERROR(EINVAL);
                goto fail;
            }
        }
        break;
        }
    }

    err = 0;
fail:
    av_freep(&profiles);
    av_freep(&entrypoints);
    return err;
}