void test()
{
    VAEntrypoint entrypoints[5];
    int num_entrypoints,slice_entrypoint;
    VAConfigAttrib attrib[2];
    VAConfigID config_id;
    unsigned int fourcc, luma_stride, chroma_u_stride, chroma_v_stride, luma_offset, chroma_u_offset;
    unsigned int chroma_v_offset, buffer_name;
    unsigned int *p_buffer;
    int i, ret;
    char c;
    int frame_width=640,  frame_height=480;
    VASurfaceID surface_id;
    VAImage image_id;
    unsigned char *usrbuf;

    usrbuf = (unsigned char*)malloc(frame_width * frame_height * 2);
    ASSERT ( usrbuf != NULL);

    VASurfaceAttribExternalBuffers  vaSurfaceExternBuf;
    VASurfaceAttrib attrib_list[2];

    va_status = vaQueryConfigEntrypoints(va_dpy, VAProfileH264Baseline, entrypoints, &num_entrypoints);
    ASSERT( VA_STATUS_SUCCESS == va_status );

    for	(slice_entrypoint = 0; slice_entrypoint < num_entrypoints; slice_entrypoint++) {
        if (entrypoints[slice_entrypoint] == VAEntrypointEncSlice)
            break;
    }
    if (slice_entrypoint == num_entrypoints) {
        /* not find Slice entry point */
        status("VAEntrypointEncSlice doesn't support, exit.\n");
        ASSERT(0);
    }

    /* find out the format for the render target, and rate control mode */
    attrib[0].type = VAConfigAttribRTFormat;
    attrib[1].type = VAConfigAttribRateControl;
    va_status = vaGetConfigAttributes(va_dpy, VAProfileH264Baseline, VAEntrypointEncSlice, &attrib[0], 2);
    ASSERT( VA_STATUS_SUCCESS == va_status );

    if ((attrib[0].value & VA_RT_FORMAT_YUV420) == 0) {
        /* not find desired YUV420 RT format */
        status("VA_RT_FORMAT_YUV420 doesn't support, exit\n");
        ASSERT(0);
    }
    if ((attrib[1].value & VA_RC_VBR) == 0) {
        /* Can't find matched RC mode */
        status("VBR mode doesn't found, exit\n");
        ASSERT(0);
    }

    attrib[0].value = VA_RT_FORMAT_YUV420; /* set to desired RT format */
    attrib[1].value = VA_RC_VBR; /* set to desired RC mode */

    va_status = vaCreateConfig(va_dpy, VAProfileH264Baseline, VAEntrypointEncSlice, &attrib[0], 2, &config_id);
    ASSERT( VA_STATUS_SUCCESS == va_status );

    attrib_list[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor;
    attrib_list[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType;
    va_status = vaGetSurfaceAttributes(va_dpy, config_id, attrib_list, 2);
    ASSERT( VA_STATUS_SUCCESS == va_status );

    if (attrib_list[0].flags != VA_SURFACE_ATTRIB_NOT_SUPPORTED) {
        status("supported memory type:\n");
        if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_VA)
            status("\tVA_SURFACE_ATTRIB_MEM_TYPE_VA\n");
        if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_V4L2)
            status("\tVA_SURFACE_ATTRIB_MEM_TYPE_V4L2\n");
        if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR)
            status("\tVA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR\n");
        if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC)
           status("\tVA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC\n");
        if (attrib_list[0].value.value.i &  VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION)
            status("\tVA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION\n");
        if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM)
            status("\tVA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM\n");
    }

    if ((attrib_list[1].flags != VA_SURFACE_ATTRIB_NOT_SUPPORTED) &&
            (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR)) {
        status("vaCreateSurfaces from external usr pointer\n");

        vaSurfaceExternBuf.buffers = (unsigned long*)malloc(sizeof(unsigned int));
        vaSurfaceExternBuf.buffers[0] = usrbuf;
        vaSurfaceExternBuf.num_buffers = 1;
        vaSurfaceExternBuf.width = frame_width;
        vaSurfaceExternBuf.height = frame_height;
        vaSurfaceExternBuf.pitches[0] = vaSurfaceExternBuf.pitches[1] = vaSurfaceExternBuf.pitches[2] = frame_width;
        //vaSurfaceExternBuf.flags = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
        vaSurfaceExternBuf.pixel_format = VA_FOURCC_NV12;
        //vaSurfaceExternBuf.pitches[0] = attribute_tpi->luma_stride;

        attrib_list[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
        attrib_list[1].value.type = VAGenericValueTypePointer;
        attrib_list[1].value.value.p = (void *)&vaSurfaceExternBuf;

        attrib_list[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
        attrib_list[0].value.type = VAGenericValueTypeInteger;
        attrib_list[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR;

        va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, frame_width, frame_height, &surface_id, 1, attrib_list, 2);
        ASSERT( VA_STATUS_SUCCESS == va_status );

        va_status = vaDeriveImage(va_dpy, surface_id, &image_id);
        ASSERT( VA_STATUS_SUCCESS == va_status );

        va_status = vaMapBuffer(va_dpy, image_id.buf, (void**)&p_buffer);
        ASSERT( VA_STATUS_SUCCESS == va_status );

        memset(p_buffer, 0x80, image_id.width * image_id.height);

        va_status = vaUnmapBuffer(va_dpy, image_id.buf);
        ASSERT( VA_STATUS_SUCCESS == va_status );

        va_status = vaDestroyImage(va_dpy, image_id.image_id);
        ASSERT( VA_STATUS_SUCCESS == va_status );

        va_status = vaDestroySurfaces(va_dpy, &surface_id, 1);
        ASSERT( VA_STATUS_SUCCESS == va_status );

    }

    va_status = vaDestroyConfig(va_dpy, config_id);
    ASSERT( VA_STATUS_SUCCESS == va_status );

    free(usrbuf);

}
Beispiel #2
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 #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
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 #5
0
static void checkIfAvailableYUV420()
{
    VAEntrypoint entrypoints[5];
    int num_entrypoints,vld_entrypoint;
    VAConfigAttrib attrib;
    VAStatus status;

    status = vaQueryConfigEntrypoints(va::display, VAProfileMPEG2Main, entrypoints, &num_entrypoints);
    CHECK_VASTATUS(status, "vaQueryConfigEntrypoints");

    for (vld_entrypoint = 0; vld_entrypoint < num_entrypoints; ++vld_entrypoint)
    {
        if (entrypoints[vld_entrypoint] == VAEntrypointVLD)
            break;
    }
    if (vld_entrypoint == num_entrypoints)
        throw std::runtime_error("Failed to find VLD entry point");

    attrib.type = VAConfigAttribRTFormat;
    vaGetConfigAttributes(va::display, VAProfileMPEG2Main, VAEntrypointVLD, &attrib, 1);
    if ((attrib.value & VA_RT_FORMAT_YUV420) == 0)
        throw std::runtime_error("Desired YUV420 RT format not found");
}
Beispiel #6
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 #7
0
static void h264_init_decoder(int width, int height)
{
    VAStatus va_status;

    if (va_context_id) {
        rfbClientLog("%s: va_dpy already initialized\n", __FUNCTION__);
    }

    if (va_dpy != NULL) {
        rfbClientLog("%s: Re-initializing H.264 decoder\n", __FUNCTION__);
    }
    else {
        rfbClientLog("%s: initializing H.264 decoder\n", __FUNCTION__);

        /* Attach VA display to local X display */
        Display *win_display = (Display *)XOpenDisplay(":0.0");
        if (win_display == NULL) {
            rfbClientErr("Can't connect to local display\n");
            exit(-1);
        }

        int major_ver, minor_ver;
        va_dpy = vaGetDisplay(win_display);
        va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
        CHECK_VASTATUS(va_status, "vaInitialize");
        rfbClientLog("%s: libva version %d.%d found\n", __FUNCTION__, major_ver, minor_ver);
    }

    /* Check for VLD entrypoint */
    int num_entrypoints;
    VAEntrypoint    entrypoints[5];
    int vld_entrypoint_found = 0;

    /* Change VAProfileH264High if needed */
    VAProfile profile = VAProfileH264High;
    va_status = vaQueryConfigEntrypoints(va_dpy, profile, entrypoints, &num_entrypoints);
    CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
    int i;
    for (i = 0; i < num_entrypoints; ++i) {
        if (entrypoints[i] == VAEntrypointVLD) {
            vld_entrypoint_found = 1;
            break;
        }
    }

    if (vld_entrypoint_found == 0) {
        rfbClientErr("VLD entrypoint not found\n");
        exit(1);
    }

    /* Create configuration for the decode pipeline */
    VAConfigAttrib attrib;
    attrib.type = VAConfigAttribRTFormat;
    va_status = vaCreateConfig(va_dpy, profile, VAEntrypointVLD, &attrib, 1, &va_config_id);
    CHECK_VASTATUS(va_status, "vaCreateConfig");

    /* Create VA surfaces */
    for (i = 0; i < SURFACE_NUM; ++i) {
        va_surface_id[i]       = VA_INVALID_ID;
        va_pic_param_buf_id[i] = VA_INVALID_ID;
        va_mat_param_buf_id[i] = VA_INVALID_ID;
        va_sp_param_buf_id[i]  = VA_INVALID_ID;
        va_d_param_buf_id[i]   = VA_INVALID_ID;
    }
    va_status = vaCreateSurfaces(va_dpy, width, height, VA_RT_FORMAT_YUV420, SURFACE_NUM, &va_surface_id[0]);
    CHECK_VASTATUS(va_status, "vaCreateSurfaces");
    for (i = 0; i < SURFACE_NUM; ++i) {
        DebugLog(("%s: va_surface_id[%d] = %p\n", __FUNCTION__, i, va_surface_id[i]));
    }

    /* Create VA context */
    va_status = vaCreateContext(va_dpy, va_config_id, width, height, 0/*VA_PROGRESSIVE*/,  &va_surface_id[0], SURFACE_NUM, &va_context_id);
    CHECK_VASTATUS(va_status, "vaCreateContext");
    DebugLog(("%s: VA context created (id: %d)\n", __FUNCTION__, va_context_id));


    /* Instantiate decode pipeline */
    va_status = vaBeginPicture(va_dpy, va_context_id, va_surface_id[0]);
    CHECK_VASTATUS(va_status, "vaBeginPicture");

    rfbClientLog("%s: H.264 decoder initialized\n", __FUNCTION__);
}
Beispiel #8
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;
}