Exemple #1
0
DisplayPtr DisplayCache::createDisplay(const NativeDisplay& nativeDisplay)
{
    NativeDisplayPtr nativeDisplayObj;
    VADisplay vaDisplay = NULL;
    DisplayPtr vaapiDisplay;
    YamiMediaCodec::AutoLock locker(m_lock);

    m_cache.remove_if(expired);

    //lockup first
    list<weak_ptr<VaapiDisplay> >::iterator it;
    for (it = m_cache.begin(); it != m_cache.end(); ++it) {
        vaapiDisplay = (*it).lock();
        if (vaapiDisplay->isCompatible(nativeDisplay)) {
            return vaapiDisplay;
        }
    }
    vaapiDisplay.reset();

    //crate new one
    DEBUG("nativeDisplay: (type : %d), (handle : 0x%x)", nativeDisplay.type, nativeDisplay.handle);

    switch (nativeDisplay.type) {
    case NATIVE_DISPLAY_AUTO:
#if __ENABLE_X11__
    case NATIVE_DISPLAY_X11:
        nativeDisplayObj.reset (new NativeDisplayX11());
        if (nativeDisplayObj && nativeDisplayObj->initialize(nativeDisplay))
            vaDisplay = vaGetDisplay((Display*)(nativeDisplayObj->nativeHandle()));
        if (vaDisplay)
            INFO("use vaapi x11 backend");
        if(vaDisplay || nativeDisplay.type == NATIVE_DISPLAY_X11)
            break;
        INFO("try to init va with x11 display (%p) but failed", (Display*)(nativeDisplayObj->nativeHandle()));
        // NATIVE_DISPLAY_AUTO continue, no break
#endif
    case NATIVE_DISPLAY_DRM:
        nativeDisplayObj.reset (new NativeDisplayDrm());
        if (nativeDisplayObj && nativeDisplayObj->initialize(nativeDisplay))
            vaDisplay = vaGetDisplayDRM(nativeDisplayObj->nativeHandle());
        INFO("use vaapi drm backend");
        break;
    default:
        break;
    }

    if (vaDisplay == NULL) {
        ERROR("vaGetDisplay failed.");
        return vaapiDisplay;
    }

    if (vaInit(vaDisplay))
        vaapiDisplay.reset(new VaapiDisplay(nativeDisplayObj, vaDisplay));

    if (vaapiDisplay) {
        weak_ptr<VaapiDisplay> weak(vaapiDisplay);
        m_cache.push_back(weak);
    }
    return vaapiDisplay;
}
Exemple #2
0
static VADisplay *create_drm_va_display(struct ra *ra)
{
    int drm_fd = (intptr_t)ra_get_native_resource(ra, "drm");
    // Note: yes, drm_fd==0 could be valid - but it's rare and doesn't fit with
    //       our slightly crappy way of passing it through, so consider 0 not
    //       valid.
    return drm_fd ? vaGetDisplayDRM(drm_fd) : NULL;
}
Exemple #3
0
static VADisplay *create_drm_va_display(GL *gl)
{
    int drm_fd = (intptr_t)gl->MPGetNativeDisplay("drm");
    // Note: yes, drm_fd==0 could be valid - but it's rare and doesn't fit with
    //       our slightly crappy way of passing it through, so consider 0 not
    //       valid.
    return drm_fd ? vaGetDisplayDRM(drm_fd) : NULL;
}
Exemple #4
0
VADisplay CVaapiProxy::GetVADisplay()
{
  return vaGetDisplayDRM(m_fd);
}
Exemple #5
0
static int Create( vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
                   const es_format_t *fmt, picture_sys_t *p_sys )
{
    if( pix_fmt != AV_PIX_FMT_VAAPI_VLD )
        return VLC_EGENERIC;

    (void) fmt;
    (void) p_sys;
#ifdef VLC_VA_BACKEND_XLIB
    if( !vlc_xlib_init( VLC_OBJECT(va) ) )
    {
        msg_Warn( va, "Ignoring VA-X11 API" );
        return VLC_EGENERIC;
    }
#endif

    VAProfile i_profile, *p_profiles_list;
    bool b_supported_profile = false;
    int i_profiles_nb = 0;
    unsigned count = 3;

    /* */
    switch( ctx->codec_id )
    {
    case AV_CODEC_ID_MPEG1VIDEO:
    case AV_CODEC_ID_MPEG2VIDEO:
        i_profile = VAProfileMPEG2Main;
        count = 4;
        break;
    case AV_CODEC_ID_MPEG4:
        i_profile = VAProfileMPEG4AdvancedSimple;
        break;
    case AV_CODEC_ID_WMV3:
        i_profile = VAProfileVC1Main;
        break;
    case AV_CODEC_ID_VC1:
        i_profile = VAProfileVC1Advanced;
        break;
    case AV_CODEC_ID_H264:
        i_profile = VAProfileH264High;
        count = 18;
        break;;
    default:
        return VLC_EGENERIC;
    }
    count += ctx->thread_count;

    vlc_va_sys_t *sys;
    void *mem;

    assert(popcount(sizeof (sys->surfaces)) == 1);
    if (unlikely(posix_memalign(&mem, sizeof (sys->surfaces), sizeof (*sys))))
       return VLC_ENOMEM;

    sys = mem;
    memset(sys, 0, sizeof (*sys));

    /* */
    sys->hw_ctx.display = NULL;
    sys->hw_ctx.config_id = VA_INVALID_ID;
    sys->hw_ctx.context_id = VA_INVALID_ID;
    sys->width = ctx->coded_width;
    sys->height = ctx->coded_height;
    sys->count = count;
    sys->available = (1 << sys->count) - 1;
    assert(count < sizeof (sys->available) * CHAR_BIT);
    assert(count * sizeof (sys->surfaces[0]) <= sizeof (sys->surfaces));

    /* Create a VA display */
#ifdef VLC_VA_BACKEND_XLIB
    sys->p_display_x11 = XOpenDisplay(NULL);
    if( !sys->p_display_x11 )
    {
        msg_Err( va, "Could not connect to X server" );
        goto error;
    }

    sys->hw_ctx.display = vaGetDisplay(sys->p_display_x11);
#endif
#ifdef VLC_VA_BACKEND_DRM
    sys->drm_fd = vlc_open("/dev/dri/card0", O_RDWR);
    if( sys->drm_fd == -1 )
    {
        msg_Err( va, "Could not access rendering device: %m" );
        goto error;
    }

    sys->hw_ctx.display = vaGetDisplayDRM(sys->drm_fd);
#endif
    if (sys->hw_ctx.display == NULL)
    {
        msg_Err( va, "Could not get a VAAPI device" );
        goto error;
    }

    int major, minor;
    if (vaInitialize(sys->hw_ctx.display, &major, &minor))
    {
        msg_Err( va, "Failed to initialize the VAAPI device" );
        goto error;
    }

    /* Check if the selected profile is supported */
    i_profiles_nb = vaMaxNumProfiles(sys->hw_ctx.display);
    p_profiles_list = calloc( i_profiles_nb, sizeof( VAProfile ) );
    if( !p_profiles_list )
        goto error;

    if (vaQueryConfigProfiles(sys->hw_ctx.display, p_profiles_list,
                              &i_profiles_nb) == VA_STATUS_SUCCESS)
    {
        for( int i = 0; i < i_profiles_nb; i++ )
        {
            if ( p_profiles_list[i] == i_profile )
            {
                b_supported_profile = true;
                break;
            }
        }
    }
    free( p_profiles_list );
    if ( !b_supported_profile )
    {
        msg_Dbg( va, "Codec and profile not supported by the hardware" );
        goto error;
    }

    /* Create a VA configuration */
    VAConfigAttrib attrib;
    memset( &attrib, 0, sizeof(attrib) );
    attrib.type = VAConfigAttribRTFormat;
    if (vaGetConfigAttributes(sys->hw_ctx.display, i_profile, VAEntrypointVLD,
                              &attrib, 1))
        goto error;

    /* Not sure what to do if not, I don't have a way to test */
    if( (attrib.value & VA_RT_FORMAT_YUV420) == 0 )
        goto error;
    if (vaCreateConfig(sys->hw_ctx.display, i_profile, VAEntrypointVLD,
                       &attrib, 1, &sys->hw_ctx.config_id))
    {
        sys->hw_ctx.config_id = VA_INVALID_ID;
        goto error;
    }

    /* Create surfaces */
    assert(ctx->coded_width > 0 && ctx->coded_height > 0);
    if (vaCreateSurfaces(sys->hw_ctx.display, VA_RT_FORMAT_YUV420,
                         ctx->coded_width, ctx->coded_height,
                         sys->surfaces, sys->count, NULL, 0))
    {
        goto error;
    }

    /* Create a context */
    if (vaCreateContext(sys->hw_ctx.display, sys->hw_ctx.config_id,
                        ctx->coded_width, ctx->coded_height, VA_PROGRESSIVE,
                        sys->surfaces, sys->count, &sys->hw_ctx.context_id))
    {
        sys->hw_ctx.context_id = VA_INVALID_ID;
        vaDestroySurfaces(sys->hw_ctx.display, sys->surfaces, sys->count);
        goto error;
    }

    if (FindFormat(sys))
        goto error;

    if (unlikely(CopyInitCache(&sys->image_cache, ctx->coded_width)))
        goto error;

    vlc_mutex_init(&sys->lock);

    msg_Dbg(va, "using %s image format 0x%08x",
            sys->do_derive ? "derive" : "get", sys->format.fourcc);

    ctx->hwaccel_context = &sys->hw_ctx;
    va->sys = sys;
    va->description = vaQueryVendorString(sys->hw_ctx.display);
    va->get = Get;
    va->release = Release;
    va->extract = Extract;
    return VLC_SUCCESS;

error:
    if (sys->hw_ctx.context_id != VA_INVALID_ID)
    {
        vaDestroyContext(sys->hw_ctx.display, sys->hw_ctx.context_id);
        vaDestroySurfaces(sys->hw_ctx.display, sys->surfaces, sys->count);
    }
    if (sys->hw_ctx.config_id != VA_INVALID_ID)
        vaDestroyConfig(sys->hw_ctx.display, sys->hw_ctx.config_id);
    if (sys->hw_ctx.display != NULL)
        vaTerminate(sys->hw_ctx.display);
#ifdef VLC_VA_BACKEND_XLIB
    if( sys->p_display_x11 != NULL )
        XCloseDisplay( sys->p_display_x11 );
#endif
#ifdef VLC_VA_BACKEND_DRM
    if( sys->drm_fd != -1 )
        close( sys->drm_fd );
#endif
    free( sys );
    return VLC_EGENERIC;
}
int
main(int argc, char *argv[])
{
    GstVaapiDisplay *display, *display2;
    guint width, height, par_n, par_d;

    gst_init(&argc, &argv);

#if USE_DRM
    g_print("#\n");
    g_print("# Create display with gst_vaapi_display_drm_new()\n");
    g_print("#\n");
    {
        display = gst_vaapi_display_drm_new(NULL);
        if (!display)
            g_error("could not create Gst/VA display");

        dump_info(display);
        gst_vaapi_display_unref(display);
    }
    g_print("\n");

    g_print("#\n");
    g_print("# Create display with gst_vaapi_display_drm_new_with_device()\n");
    g_print("#\n");
    {
        int drm_device;

        drm_device = open(DRM_DEVICE_PATH, O_RDWR|O_CLOEXEC);
        if (drm_device < 0)
            g_error("could not open DRM device");

        display = gst_vaapi_display_drm_new_with_device(drm_device);
        if (!display)
            g_error("could not create Gst/VA display");

        dump_info(display);
        gst_vaapi_display_unref(display);
        close(drm_device);
    }
    g_print("\n");

    g_print("#\n");
    g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayDRM()]\n");
    g_print("#\n");
    {
        int drm_device;
        VADisplay va_display;

        drm_device = open(DRM_DEVICE_PATH, O_RDWR|O_CLOEXEC);
        if (drm_device < 0)
            g_error("could not open DRM device");

        va_display = vaGetDisplayDRM(drm_device);
        if (!va_display)
            g_error("could not create VA display");

        display = gst_vaapi_display_new_with_display(va_display);
        if (!display)
            g_error("could not create Gst/VA display");

        dump_info(display);
        gst_vaapi_display_unref(display);
        close(drm_device);
    }
    g_print("\n");
#endif

#if USE_X11
    g_print("#\n");
    g_print("# Create display with gst_vaapi_display_x11_new()\n");
    g_print("#\n");
    {
        display = gst_vaapi_display_x11_new(NULL);
        if (!display)
            g_error("could not create Gst/VA display");

        if (CHECK_DISPLAY_CACHE) {
            display2 = gst_vaapi_display_x11_new(NULL);

            /* Check for the same X11 display */
            g_assert(gst_vaapi_display_x11_get_display(
                         GST_VAAPI_DISPLAY_X11(display)) ==
                     gst_vaapi_display_x11_get_display(
                         GST_VAAPI_DISPLAY_X11(display2)));

            /* Check for the same VA display */
            g_assert(gst_vaapi_display_get_display(display) ==
                     gst_vaapi_display_get_display(display2));

            gst_vaapi_display_unref(display2);

#if USE_GLX
            display2 = gst_vaapi_display_glx_new(NULL);

            /* Check for the different X11 display */
            /* XXX: it is also desired to cache underlying X11 displays */
            g_assert(gst_vaapi_display_x11_get_display(
                         GST_VAAPI_DISPLAY_X11(display)) !=
                     gst_vaapi_display_x11_get_display(
                         GST_VAAPI_DISPLAY_X11(display2)));

            /* Check for different VA display */
            g_assert(gst_vaapi_display_get_display(display) !=
                     gst_vaapi_display_get_display(display2));

            gst_vaapi_display_unref(display2);
#endif
        }

        gst_vaapi_display_get_size(display, &width, &height);
        g_print("Display size: %ux%u\n", width, height);

        gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d);
        g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d);

        dump_info(display);
        gst_vaapi_display_unref(display);
    }
    g_print("\n");

    g_print("#\n");
    g_print("# Create display with gst_vaapi_display_x11_new_with_display()\n");
    g_print("#\n");
    {
        Display *x11_display;

        x11_display = XOpenDisplay(NULL);
        if (!x11_display)
            g_error("could not create X11 display");

        display = gst_vaapi_display_x11_new_with_display(x11_display);
        if (!display)
            g_error("could not create Gst/VA display");

        if (CHECK_DISPLAY_CACHE) {
            display2 = gst_vaapi_display_x11_new_with_display(x11_display);

            /* Check for the same VA display */
            g_assert(gst_vaapi_display_get_display(display) ==
                     gst_vaapi_display_get_display(display2));

            gst_vaapi_display_unref(display2);
        }

        dump_info(display);
        gst_vaapi_display_unref(display);
        XCloseDisplay(x11_display);
    }
    g_print("\n");

    g_print("#\n");
    g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplay()]\n");
    g_print("#\n");
    {
        Display *x11_display;
        VADisplay va_display;

        x11_display = XOpenDisplay(NULL);
        if (!x11_display)
            g_error("could not create X11 display");

        va_display = vaGetDisplay(x11_display);
        if (!va_display)
            g_error("could not create VA display");

        display = gst_vaapi_display_new_with_display(va_display);
        if (!display)
            g_error("could not create Gst/VA display");

        dump_info(display);
        gst_vaapi_display_unref(display);
        XCloseDisplay(x11_display);
    }
    g_print("\n");
#endif

#if USE_GLX
    g_print("#\n");
    g_print("# Create display with gst_vaapi_display_glx_new()\n");
    g_print("#\n");
    {
        display = gst_vaapi_display_glx_new(NULL);
        if (!display)
            g_error("could not create Gst/VA display");

        if (CHECK_DISPLAY_CACHE) {
            display2 = gst_vaapi_display_glx_new(NULL);

            /* Check for the same X11 display */
            g_assert(gst_vaapi_display_x11_get_display(
                         GST_VAAPI_DISPLAY_X11(display)) ==
                     gst_vaapi_display_x11_get_display(
                         GST_VAAPI_DISPLAY_X11(display2)));

            /* Check for the same VA display */
            g_assert(gst_vaapi_display_get_display(display) ==
                     gst_vaapi_display_get_display(display2));

            gst_vaapi_display_unref(display2);

            display2 = gst_vaapi_display_x11_new(NULL);

            /* Check for the same X11 display */
            g_assert(gst_vaapi_display_x11_get_display(
                         GST_VAAPI_DISPLAY_X11(display)) ==
                     gst_vaapi_display_x11_get_display(
                         GST_VAAPI_DISPLAY_X11(display2)));

            /* Check for the same VA display */
            g_assert(gst_vaapi_display_get_display(display) ==
                     gst_vaapi_display_get_display(display2));

            gst_vaapi_display_unref(display2);
        }

        gst_vaapi_display_get_size(display, &width, &height);
        g_print("Display size: %ux%u\n", width, height);

        gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d);
        g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d);

        dump_info(display);
        gst_vaapi_display_unref(display);
    }
    g_print("\n");

    g_print("#\n");
    g_print("# Create display with gst_vaapi_display_glx_new_with_display()\n");
    g_print("#\n");
    {
        Display *x11_display;

        x11_display = XOpenDisplay(NULL);
        if (!x11_display)
            g_error("could not create X11 display");

        display = gst_vaapi_display_glx_new_with_display(x11_display);
        if (!display)
            g_error("could not create Gst/VA display");

        dump_info(display);
        gst_vaapi_display_unref(display);
        XCloseDisplay(x11_display);
    }
    g_print("\n");

#ifdef HAVE_VA_VA_GLX_H
    g_print("#\n");
    g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayGLX()]\n");
    g_print("#\n");
    {
        Display *x11_display;
        VADisplay va_display;

        x11_display = XOpenDisplay(NULL);
        if (!x11_display)
            g_error("could not create X11 display");

        va_display = vaGetDisplayGLX(x11_display);
        if (!va_display)
            g_error("could not create VA display");

        display = gst_vaapi_display_new_with_display(va_display);
        if (!display)
            g_error("could not create Gst/VA display");

        dump_info(display);
        gst_vaapi_display_unref(display);
        XCloseDisplay(x11_display);
    }
    g_print("\n");
#endif
#endif

#if USE_WAYLAND
    g_print("#\n");
    g_print("# Create display with gst_vaapi_display_wayland_new()\n");
    g_print("#\n");
    {
        display = gst_vaapi_display_wayland_new(NULL);
        if (!display)
            g_error("could not create Gst/VA display");

        gst_vaapi_display_get_size(display, &width, &height);
        g_print("Display size: %ux%u\n", width, height);

        gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d);
        g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d);

        dump_info(display);
        gst_vaapi_display_unref(display);
    }
    g_print("\n");
#endif

    gst_deinit();
    return 0;
}