bool VAApiWriter::open() { addParam( "Zoom" ); addParam( "AspectRatio" ); addParam( "Deinterlace" ); addParam( "PrepareForHWBobDeint", true ); addParam( "Hue" ); addParam( "Saturation" ); addParam( "Brightness" ); addParam( "Contrast" ); clr(); VADisp = vaGetDisplay( QX11Info::display() ); int minor, major; if ( vaInitialize( VADisp, &minor, &major ) == VA_STATUS_SUCCESS ) { const QString vendor = vaQueryVendorString( VADisp ); isVDPAU = vendor.contains( "VDPAU" ); if ( isVDPAU && !allowVDPAU ) return false; isXvBA = vendor.contains( "XvBA" ); int numProfiles = vaMaxNumProfiles( VADisp ); VAProfile profiles[ numProfiles ]; if ( vaQueryConfigProfiles( VADisp, profiles, &numProfiles ) == VA_STATUS_SUCCESS ) { for ( int i = 0 ; i < numProfiles ; ++i ) profileList.push_back( profiles[ i ] ); return true; } } return false; }
static gboolean gst_vaapi_display_x11_get_display_info( GstVaapiDisplay *display, GstVaapiDisplayInfo *info ) { GstVaapiDisplayX11Private * const priv = GST_VAAPI_DISPLAY_X11(display)->priv; GstVaapiDisplayCache *cache; const GstVaapiDisplayInfo *cached_info; /* Return any cached info even if child has its own VA display */ cache = gst_vaapi_display_get_cache(); if (!cache) return FALSE; cached_info = gst_vaapi_display_cache_lookup_by_native_display( cache, priv->x11_display); if (cached_info) { *info = *cached_info; return TRUE; } /* Otherwise, create VA display if there is none already */ info->native_display = priv->x11_display; info->display_name = priv->display_name; if (!info->va_display) { info->va_display = vaGetDisplay(priv->x11_display); if (!info->va_display) return FALSE; info->display_type = GST_VAAPI_DISPLAY_TYPE_X11; } return TRUE; }
// Return a suitable VADisplay for VA API VADisplay vaGetDisplayGLX(Display *native_dpy) { VADisplay dpy = NULL; VADisplayContextP pDisplayContext = NULL; VADisplayContextGLXP pDisplayContextGLX = NULL; VADriverContextP pDriverContext; VADriverContextGLXP pDriverContextGLX = NULL; dpy = vaGetDisplay(native_dpy); if (!dpy) return NULL; pDisplayContext = (VADisplayContextP)dpy; pDriverContext = pDisplayContext->pDriverContext; pDisplayContextGLX = calloc(1, sizeof(*pDisplayContextGLX)); if (!pDisplayContextGLX) goto error; pDriverContextGLX = calloc(1, sizeof(*pDriverContextGLX)); if (!pDriverContextGLX) goto error; pDisplayContextGLX->vaDestroy = pDisplayContext->vaDestroy; pDisplayContext->vaDestroy = va_DisplayContextDestroy; pDisplayContext->opaque = pDisplayContextGLX; pDriverContext->glx = pDriverContextGLX; return dpy; error: free(pDriverContextGLX); free(pDisplayContextGLX); pDisplayContext->vaDestroy(pDisplayContext); return NULL; }
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; }
static gboolean gst_vaapi_display_x11_get_display_info (GstVaapiDisplay * display, GstVaapiDisplayInfo * info) { GstVaapiDisplayX11Private *const priv = GST_VAAPI_DISPLAY_X11_PRIVATE (display); info->native_display = priv->x11_display; info->display_name = priv->display_name; if (!info->va_display) { info->va_display = vaGetDisplay (priv->x11_display); if (!info->va_display) return FALSE; } return TRUE; }
bool VaapiEncoderBase::initVA() { FUNC_ENTER(); if (!m_externalDisplay) m_xDisplay = XOpenDisplay(NULL); if (!m_xDisplay) { ERROR("no x display."); return false; } int majorVersion, minorVersion; VAStatus vaStatus; m_display = vaGetDisplay(m_xDisplay); if (m_display == NULL) { ERROR("vaGetDisplay failed."); goto error; } vaStatus= vaInitialize(m_display, &majorVersion, &minorVersion); DEBUG("vaInitialize \n"); if (!checkVaapiStatus(vaStatus, "vaInitialize")) goto error; DEBUG("profile = %d", m_videoParamCommon.profile); vaStatus = vaCreateConfig(m_display, m_videoParamCommon.profile, m_entrypoint, NULL, 0, &m_config); if (!checkVaapiStatus(vaStatus, "vaCreateConfig ")) goto error; vaStatus = vaCreateContext(m_display, m_config, m_videoParamCommon.resolution.width, m_videoParamCommon.resolution.height, VA_PROGRESSIVE, 0, 0, &m_context); if (!checkVaapiStatus(vaStatus, "vaCreateContext ")) goto error; return true; error: cleanupVA(); return false; }
static bool ffva_display_x11_open(FFVADisplayX11 *display) { FFVADisplay * const base_display = (FFVADisplay*)display; base_display->native_display = XOpenDisplay(base_display->display_name); if (!base_display->native_display) goto error_open_display; base_display->va_display = vaGetDisplay(base_display->native_display); return true; /* ERRORS */ error_open_display: av_log(display, AV_LOG_ERROR, "failed to open display `%s'\n", base_display->display_name); return false; }
OMXVideoDecoderVP9HWR::OMXVideoDecoderVP9HWR() { LOGV("OMXVideoDecoderVP9HWR is constructed."); mNumFrameBuffer = 0; mCtx = NULL; mNativeBufferCount = OUTPORT_NATIVE_BUFFER_COUNT; extUtilBufferCount = 0; extMappedNativeBufferCount = 0; BuildHandlerList(); mDecodedImageWidth = 0; mDecodedImageHeight = 0; mDecodedImageNewWidth = 0; mDecodedImageNewHeight = 0; #ifdef DECODE_WITH_GRALLOC_BUFFER // setup va VAStatus vaStatus = VA_STATUS_SUCCESS; mDisplay = new Display; *mDisplay = ANDROID_DISPLAY_HANDLE; mVADisplay = vaGetDisplay(mDisplay); if (mVADisplay == NULL) { LOGE("vaGetDisplay failed."); } int majorVersion, minorVersion; vaStatus = vaInitialize(mVADisplay, &majorVersion, &minorVersion); if (vaStatus != VA_STATUS_SUCCESS) { LOGE("vaInitialize failed."); } else { LOGV("va majorVersion=%d, minorVersion=%d", majorVersion, minorVersion); } #endif }
static VADisplay *create_x11_va_display(struct ra *ra) { Display *x11 = ra_get_native_resource(ra, "x11"); return x11 ? vaGetDisplay(x11) : NULL; }
static VADisplay gst_vaapi_display_x11_get_va_display(GstVaapiDisplay *display) { return vaGetDisplay(GST_VAAPI_DISPLAY_XDISPLAY(display)); }
Decode_Status VaapiDecoderBase::setupVA(uint32_t numSurface, VAProfile profile) { INFO("base: setup VA"); uint32_t i; VASurfaceID *surfaces; VideoSurfaceBuffer *buf; VaapiSurface *suf; Decode_Status status; VAStatus vaStatus = VA_STATUS_SUCCESS; if (m_enableNativeBuffersFlag == true) { numSurface = 20; //NATIVE_WINDOW_COUNT; } if (m_VAStarted) { return DECODE_SUCCESS; } if (m_VADisplay != NULL) { WARNING("VA is partially started."); return DECODE_FAIL; } #ifdef ANDROID m_display = new Display; *m_display = ANDROID_DISPLAY_HANDLE; #else if (!m_display) { m_display = XOpenDisplay(NULL); m_ownNativeDisplay = true; } #if __PLATFORM_BYT__ if (setenv("LIBVA_DRIVER_NAME", "wrapper", 1) == 0) { INFO("setting LIBVA_DRIVER_NAME to wrapper for chromeos"); } #endif #endif m_VADisplay = vaGetDisplay(m_display); if (m_VADisplay == NULL) { ERROR("vaGetDisplay failed."); return DECODE_DRIVER_FAIL; } int majorVersion, minorVersion; vaStatus = vaInitialize(m_VADisplay, &majorVersion, &minorVersion); checkVaapiStatus(vaStatus, "vaInitialize"); VAConfigAttrib attrib; attrib.type = VAConfigAttribRTFormat; attrib.value = VA_RT_FORMAT_YUV420; INFO("base:the profile = %d", profile); vaStatus = vaCreateConfig(m_VADisplay, profile, VAEntrypointVLD, &attrib, 1, &m_VAConfig); checkVaapiStatus(vaStatus, "vaCreateConfig"); m_configBuffer.surfaceNumber = numSurface; m_bufPool = new VaapiSurfaceBufferPool(m_VADisplay, &m_configBuffer); surfaces = new VASurfaceID[numSurface]; for (i = 0; i < numSurface; i++) { surfaces[i] = VA_INVALID_SURFACE; buf = m_bufPool->getBufferByIndex(i); suf = m_bufPool->getVaapiSurface(buf); if (suf) surfaces[i] = suf->getID(); } vaStatus = vaCreateContext(m_VADisplay, m_VAConfig, m_videoFormatInfo.width, m_videoFormatInfo.height, 0, surfaces, numSurface, &m_VAContext); checkVaapiStatus(vaStatus, "vaCreateContext"); VADisplayAttribute rotate; rotate.type = VADisplayAttribRotation; rotate.value = VA_ROTATION_NONE; if (m_configBuffer.rotationDegrees == 0) rotate.value = VA_ROTATION_NONE; else if (m_configBuffer.rotationDegrees == 90) rotate.value = VA_ROTATION_90; else if (m_configBuffer.rotationDegrees == 180) rotate.value = VA_ROTATION_180; else if (m_configBuffer.rotationDegrees == 270) rotate.value = VA_ROTATION_270; vaStatus = vaSetDisplayAttributes(m_VADisplay, &rotate, 1); m_videoFormatInfo.surfaceNumber = numSurface; m_videoFormatInfo.ctxSurfaces = surfaces; if (!(m_configBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER)) { m_videoFormatInfo.surfaceWidth = m_videoFormatInfo.width; m_videoFormatInfo.surfaceHeight = m_videoFormatInfo.height; } m_VAStarted = true; return DECODE_SUCCESS; }
int tables_open_display(void) { int retval = 0; int major, minor; pthread_mutex_init(&display.lock, NULL); pthread_mutex_lock(&display.lock); display.x = XOpenDisplay(NULL); if (!display.x) { trace_error("%s, can't open X Display\n", __func__); retval = 1; goto quit; } if (config.quirks.x_synchronize) XSynchronize(display.x, True); #if HAVE_HWDEC display.va = vaGetDisplay(display.x); VAStatus status = vaInitialize(display.va, &major, &minor); if (status == VA_STATUS_SUCCESS) { trace_info_f("libva version %d.%d\n", major, minor); display.va_available = 1; } else { // TODO: remember? trace_info_f("no libva\n"); display.va_available = 0; } #endif // HAVE_HWDEC if (!glXQueryVersion(display.x, &major, &minor)) { trace_error("%s, glXQueryVersion returned False\n", __func__); } else { trace_info_f("GLX version %d.%d\n", major, minor); } check_glx_extensions(); // initialize screensaver inhibition library screensaver_connect(); display.screensaver_types = screensaver_type_detect(display.x); gchar *s = g_strdup_printf("screensavers found:%s%s%s%s%s", (display.screensaver_types & SST_XSCREENSAVER) ? " XScreenSaver" : "", (display.screensaver_types & SST_FDO_SCREENSAVER) ? " fd.o-screensaver" : "", (display.screensaver_types & SST_CINNAMON_SCREENSAVER) ? " cinnamon-screensaver" : "", (display.screensaver_types & SST_GNOME_SCREENSAVER) ? " gnome-screensaver" : "", (display.screensaver_types & SST_KDE_SCREENSAVER) ? " kscreensaver" : ""); trace_info_f("%s\n", s); g_free(s); // create transparent cursor const char t_pixmap_data = 0; XColor t_color = {}; Pixmap t_pixmap = XCreateBitmapFromData(display.x, DefaultRootWindow(display.x), &t_pixmap_data, 1, 1); display.transparent_cursor = XCreatePixmapCursor(display.x, t_pixmap, t_pixmap, &t_color, &t_color, 0, 0); XFreePixmap(display.x, t_pixmap); // determine minimal size across all screens display.min_width = (uint32_t)-1; display.min_height = (uint32_t)-1; XRRScreenResources *sr = XRRGetScreenResources(display.x, DefaultRootWindow(display.x)); if (sr) { for (int k = 0; k < sr->ncrtc; k ++) { XRRCrtcInfo *ci = XRRGetCrtcInfo(display.x, sr, sr->crtcs[k]); if (ci && ci->width > 0 && ci->height > 0) { display.min_width = MIN(display.min_width, ci->width); display.min_height = MIN(display.min_height, ci->height); } if (ci) XRRFreeCrtcInfo(ci); } XRRFreeScreenResources(sr); } if (display.min_width == (uint32_t)-1 || display.min_height == (uint32_t)-1) { display.min_width = 300; display.min_height = 300; } // apply size override from the configuration file if (config.fullscreen_width > 0) display.min_width = config.fullscreen_width; if (config.fullscreen_height > 0) display.min_height = config.fullscreen_height; display.pictfmt_rgb24 = XRenderFindStandardFormat(display.x, PictStandardRGB24); display.pictfmt_argb32 = XRenderFindStandardFormat(display.x, PictStandardARGB32); quit: pthread_mutex_unlock(&display.lock); return retval; }
static int Open( vlc_va_vaapi_t *p_va, int i_codec_id ) { VAProfile i_profile; int i_surface_count; /* */ switch( i_codec_id ) { case CODEC_ID_MPEG1VIDEO: case CODEC_ID_MPEG2VIDEO: i_profile = VAProfileMPEG2Main; i_surface_count = 2+1; break; case CODEC_ID_MPEG4: i_profile = VAProfileMPEG4AdvancedSimple; i_surface_count = 2+1; break; case CODEC_ID_WMV3: i_profile = VAProfileVC1Main; i_surface_count = 2+1; break; case CODEC_ID_VC1: i_profile = VAProfileVC1Advanced; i_surface_count = 2+1; break; case CODEC_ID_H264: i_profile = VAProfileH264High; i_surface_count = 16+1; break; default: return VLC_EGENERIC; } /* */ memset( p_va, 0, sizeof(*p_va) ); p_va->i_config_id = VA_INVALID_ID; p_va->i_context_id = VA_INVALID_ID; p_va->image.image_id = VA_INVALID_ID; /* Create a VA display */ p_va->p_display_x11 = XOpenDisplay(NULL); if( !p_va->p_display_x11 ) goto error; p_va->p_display = vaGetDisplay( p_va->p_display_x11 ); if( !p_va->p_display ) goto error; if( vaInitialize( p_va->p_display, &p_va->i_version_major, &p_va->i_version_minor ) ) goto error; /* Create a VA configuration */ VAConfigAttrib attrib; memset( &attrib, 0, sizeof(attrib) ); attrib.type = VAConfigAttribRTFormat; if( vaGetConfigAttributes( p_va->p_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( p_va->p_display, i_profile, VAEntrypointVLD, &attrib, 1, &p_va->i_config_id ) ) { p_va->i_config_id = VA_INVALID_ID; goto error; } p_va->i_surface_count = i_surface_count; if( asprintf( &p_va->va.description, "VA API version %d.%d", p_va->i_version_major, p_va->i_version_minor ) < 0 ) p_va->va.description = NULL; return VLC_SUCCESS; error: return VLC_EGENERIC; }
bool Create(void) { m_x_disp = OpenMythXDisplay(); if (!m_x_disp) return false; MythXLocker locker(m_x_disp); if (m_va_disp_type == kVADisplayGLX) { MythMainWindow *mw = GetMythMainWindow(); if (!mw) return false; MythRenderOpenGL *gl = static_cast<MythRenderOpenGL*>(mw->GetRenderDevice()); if (!gl) { LOG(VB_PLAYBACK, LOG_ERR, LOC + QString("Failed to get OpenGL context - you must use the " "OpenGL UI painter for VAAPI GLX support.")); return false; } gl->makeCurrent(); Display *display = glXGetCurrentDisplay(); gl->doneCurrent(); m_va_disp = vaGetDisplayGLX(display); } else { m_va_disp = vaGetDisplay(m_x_disp->GetDisplay()); } if (!m_va_disp) { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create VADisplay"); return false; } int major_ver, minor_ver; INIT_ST; va_status = vaInitialize(m_va_disp, &major_ver, &minor_ver); CHECK_ST; if (ok) m_driver = vaQueryVendorString(m_va_disp); static bool debugged = false; if (ok && !debugged) { debugged = true; LOG(VB_GENERAL, LOG_INFO, LOC + QString("Version: %1.%2") .arg(major_ver).arg(minor_ver)); LOG(VB_GENERAL, LOG_INFO, LOC + QString("Driver : %1").arg(m_driver)); } if (ok) { LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Created VAAPI %1 display") .arg(m_va_disp_type == kVADisplayGLX ? "GLX" : "X11")); } return ok; }
VdpStatus vdpDeviceCreateX11(Display *display_orig, int screen, VdpDevice *device, VdpGetProcAddress **get_proc_address) { if (!display_orig || !device) return VDP_STATUS_INVALID_POINTER; // Let's get own connection to the X server Display *display = handle_xdpy_ref(display_orig); if (NULL == display) return VDP_STATUS_ERROR; if (global.quirks.buggy_XCloseDisplay) { // XCloseDisplay could segfault on fglrx. To avoid calling XCloseDisplay, // make one more reference to xdpy copy. handle_xdpy_ref(display_orig); } VdpDeviceData *data = calloc(1, sizeof(VdpDeviceData)); if (NULL == data) return VDP_STATUS_RESOURCES; glx_ctx_lock(); // use glx lock to serialize X calls data->type = HANDLETYPE_DEVICE; data->display = display; data->display_orig = display_orig; // save supplied pointer too data->screen = screen; data->refcount = 0; pthread_mutex_init(&data->refcount_mutex, NULL); data->root = DefaultRootWindow(display); XWindowAttributes wnd_attrs; XGetWindowAttributes(display, data->root, &wnd_attrs); data->color_depth = wnd_attrs.depth; data->fn.glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *)"glXBindTexImageEXT"); data->fn.glXReleaseTexImageEXT = (PFNGLXRELEASETEXIMAGEEXTPROC)glXGetProcAddress((GLubyte *)"glXReleaseTexImageEXT"); glx_ctx_unlock(); if (!data->fn.glXBindTexImageEXT || !data->fn.glXReleaseTexImageEXT) { traceError("error (%s): can't get glXBindTexImageEXT address\n"); free(data); return VDP_STATUS_RESOURCES; } // create master GLX context to share data between further created ones glx_ctx_ref_glc_hash_table(display, screen); data->root_glc = glx_ctx_get_root_context(); glx_ctx_push_thread_local(data); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // initialize VAAPI if (global.quirks.avoid_va) { // pretend there is no VA-API available data->va_available = 0; } else { data->va_dpy = vaGetDisplay(display); data->va_available = 0; VAStatus status = vaInitialize(data->va_dpy, &data->va_version_major, &data->va_version_minor); if (VA_STATUS_SUCCESS == status) { data->va_available = 1; traceInfo("libva (version %d.%d) library initialized\n", data->va_version_major, data->va_version_minor); } else { data->va_available = 0; traceInfo("warning: failed to initialize libva. " "No video decode acceleration available.\n"); } } compile_shaders(data); glGenTextures(1, &data->watermark_tex_id); glBindTexture(GL_TEXTURE_2D, data->watermark_tex_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, watermark_width, watermark_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, watermark_data); glFinish(); *device = handle_insert(data); if (get_proc_address) *get_proc_address = &vdpGetProcAddress; GLenum gl_error = glGetError(); glx_ctx_pop(); if (GL_NO_ERROR != gl_error) { traceError("error (%s): gl error %d\n", __func__, gl_error); return VDP_STATUS_ERROR; } return VDP_STATUS_OK; }
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; }
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; }
static VADisplay *create_x11_va_display(GL *gl) { Display *x11 = gl->MPGetNativeDisplay("x11"); return x11 ? vaGetDisplay(x11) : NULL; }
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__); }
int main(int argc,char **argv) { int major_ver, minor_ver; VAStatus va_status; pthread_t thread1; int ret; char c; int i; char str_src_fmt[5], str_dst_fmt[5]; static struct option long_options[] = { {"fmt1", required_argument, NULL, '1'}, {"fmt2", required_argument, NULL, '2'}, {0, 0, 0, 0} }; while ((c =getopt_long(argc,argv,"w:h:g:r:d:f:tcep?n:1:2:v", long_options, NULL)) != EOF) { switch (c) { case '?': printf("putsurface <options>\n"); printf(" -g <widthxheight+x_location+y_location> window geometry\n"); printf(" -w/-h resolution of surface\n"); printf(" -r <framerate>\n"); printf(" -d the dimension of black/write square box, default is 32\n"); printf(" -t multi-threads\n"); printf(" -c test clipbox\n"); printf(" -f <1/2> top field, or bottom field\n"); printf(" -1 source format (fourcc) for color conversion test\n"); printf(" -2 dest format (fourcc) for color conversion test\n"); printf(" --fmt1 same to -1\n"); printf(" --fmt2 same to -2\n"); printf(" -v verbose output\n"); exit(0); break; case 'g': ret = sscanf(optarg, "%dx%d+%d+%d", &win_width, &win_height, &win_x, &win_y); if (ret != 4) { printf("invalid window geometry, must be widthxheight+x_location+y_location\n"); exit(0); } else printf("Create window at (%d, %d), width = %d, height = %d\n", win_x, win_y, win_width, win_height); break; case 'r': frame_rate = atoi(optarg); break; case 'w': surface_width = atoi(optarg); break; case 'h': surface_height = atoi(optarg); break; case 'n': frame_num_total = atoi(optarg); break; case 'd': box_width = atoi(optarg); break; case 't': multi_thread = 1; printf("Two threads to do vaPutSurface\n"); break; case 'e': check_event = 0; break; case 'p': put_pixmap = 1; break; case 'c': test_clip = 1; break; case 'f': if (atoi(optarg) == 1) { printf("Display TOP field\n"); display_field = VA_TOP_FIELD; } else if (atoi(optarg) == 2) { printf("Display BOTTOM field\n"); display_field = VA_BOTTOM_FIELD; } else printf("The validate input for -f is: 1(top field)/2(bottom field)\n"); break; case '1': sscanf(optarg, "%s", str_src_fmt); csc_src_fourcc = map_str_to_vafourcc (str_src_fmt); if (!csc_src_fourcc) { printf("invalid fmt1: %s\n", str_src_fmt ); exit(0); } break; case '2': sscanf(optarg, "%s", str_dst_fmt); csc_dst_fourcc = map_str_to_vafourcc (str_dst_fmt); if (!csc_dst_fourcc) { printf("invalid fmt1: %s\n", str_dst_fmt ); exit(0); } break; case 'v': verbose = 1; printf("Enable verbose output\n"); break; } } if (csc_src_fourcc && csc_dst_fourcc) { test_color_conversion = 1; } win_display = (void *)open_display(); if (win_display == NULL) { fprintf(stderr, "Can't open the connection of display!\n"); exit(-1); } create_window(win_display, win_x, win_y, win_width, win_height); va_dpy = vaGetDisplay(win_display); va_status = vaInitialize(va_dpy, &major_ver, &minor_ver); CHECK_VASTATUS(va_status, "vaInitialize"); if (test_color_conversion) { ret = csc_preparation(); } if (!test_color_conversion || !ret ) { va_status = vaCreateSurfaces( va_dpy, VA_RT_FORMAT_YUV420, surface_width, surface_height, &surface_id[0], SURFACE_NUM, NULL, 0 ); } CHECK_VASTATUS(va_status, "vaCreateSurfaces"); if (multi_thread == 0) /* upload the content for all surfaces */ upload_source_YUV_once_for_all(); if (check_event) pthread_mutex_init(&gmutex, NULL); for(i = 0; i< SURFACE_NUM; i++) pthread_mutex_init(&surface_mutex[i], NULL); if (multi_thread == 1) ret = pthread_create(&thread1, NULL, putsurface_thread, (void*)drawable_thread1); putsurface_thread((void *)drawable_thread0); if (multi_thread == 1) pthread_join(thread1, (void **)&ret); printf("thread1 is free\n"); if (test_color_conversion) { // destroy temp surface/image va_status = vaDestroySurfaces(va_dpy, &csc_render_surface, 1); CHECK_VASTATUS(va_status,"vaDestroySurfaces"); va_status = vaDestroyImage(va_dpy, csc_dst_fourcc_image.image_id); CHECK_VASTATUS(va_status,"vaDestroyImage"); } if (vpp_config_id != VA_INVALID_ID) { vaDestroyConfig (va_dpy, vpp_config_id); vpp_config_id = VA_INVALID_ID; } vaDestroySurfaces(va_dpy,&surface_id[0],SURFACE_NUM); vaTerminate(va_dpy); free(va_image_formats); free(va_surface_attribs); close_display(win_display); return 0; }
static int create(struct gl_hwdec *hw) { if (hw->hwctx) return -1; Display *x11disp = glXGetCurrentDisplay(); if (!x11disp) return -1; int x11scr = DefaultScreen(x11disp); struct priv *p = talloc_zero(hw, struct priv); hw->priv = p; p->log = hw->log; p->xdisplay = x11disp; const char *glxext = glXQueryExtensionsString(x11disp, x11scr); if (!glxext || !strstr(glxext, "GLX_EXT_texture_from_pixmap")) return -1; p->glXBindTexImage = (void*)glXGetProcAddressARB((void*)"glXBindTexImageEXT"); p->glXReleaseTexImage = (void*)glXGetProcAddressARB((void*)"glXReleaseTexImageEXT"); if (!p->glXBindTexImage || !p->glXReleaseTexImage) return -1; p->display = vaGetDisplay(x11disp); if (!p->display) return -1; p->ctx = va_initialize(p->display, p->log, true); if (!p->ctx) { vaTerminate(p->display); return -1; } if (hw->reject_emulated && va_guess_if_emulated(p->ctx)) { destroy(hw); return -1; } int attribs[] = { GLX_BIND_TO_TEXTURE_RGBA_EXT, True, GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, GLX_Y_INVERTED_EXT, True, GLX_DOUBLEBUFFER, False, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 0, None }; int fbcount; GLXFBConfig *fbc = glXChooseFBConfig(x11disp, x11scr, attribs, &fbcount); if (fbcount) p->fbc = fbc[0]; if (fbc) XFree(fbc); if (!fbcount) { MP_VERBOSE(p, "No texture-from-pixmap support.\n"); destroy(hw); return -1; } hw->hwctx = &p->ctx->hwctx; hw->converted_imgfmt = IMGFMT_RGB0; return 0; }
static int Open( vlc_va_vaapi_t *p_va, int i_codec_id ) { VAProfile i_profile, *p_profiles_list; bool b_supported_profile = false; int i_profiles_nb = 0; int i_surface_count; /* */ switch( i_codec_id ) { case CODEC_ID_MPEG1VIDEO: case CODEC_ID_MPEG2VIDEO: i_profile = VAProfileMPEG2Main; i_surface_count = 2+1; break; case CODEC_ID_MPEG4: i_profile = VAProfileMPEG4AdvancedSimple; i_surface_count = 2+1; break; case CODEC_ID_WMV3: i_profile = VAProfileVC1Main; i_surface_count = 2+1; break; case CODEC_ID_VC1: i_profile = VAProfileVC1Advanced; i_surface_count = 2+1; break; case CODEC_ID_H264: i_profile = VAProfileH264High; i_surface_count = 16+1; break; default: return VLC_EGENERIC; } /* */ memset( p_va, 0, sizeof(*p_va) ); p_va->i_config_id = VA_INVALID_ID; p_va->i_context_id = VA_INVALID_ID; p_va->image.image_id = VA_INVALID_ID; /* Create a VA display */ p_va->p_display_x11 = XOpenDisplay(NULL); if( !p_va->p_display_x11 ) goto error; p_va->p_display = vaGetDisplay( p_va->p_display_x11 ); if( !p_va->p_display ) goto error; if( vaInitialize( p_va->p_display, &p_va->i_version_major, &p_va->i_version_minor ) ) goto error; /* Check if the selected profile is supported */ i_profiles_nb = vaMaxNumProfiles( p_va->p_display ); p_profiles_list = calloc( i_profiles_nb, sizeof( VAProfile ) ); if ( !p_profiles_list ) goto error; VAStatus i_status = vaQueryConfigProfiles( p_va->p_display, p_profiles_list, &i_profiles_nb ); if ( i_status == 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 ) goto error; /* Create a VA configuration */ VAConfigAttrib attrib; memset( &attrib, 0, sizeof(attrib) ); attrib.type = VAConfigAttribRTFormat; if( vaGetConfigAttributes( p_va->p_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( p_va->p_display, i_profile, VAEntrypointVLD, &attrib, 1, &p_va->i_config_id ) ) { p_va->i_config_id = VA_INVALID_ID; goto error; } p_va->i_surface_count = i_surface_count; p_va->b_supports_derive = false; if( asprintf( &p_va->va.description, "VA API version %d.%d", p_va->i_version_major, p_va->i_version_minor ) < 0 ) p_va->va.description = NULL; return VLC_SUCCESS; error: return VLC_EGENERIC; }
int main(int argc,char **argv) { int major_ver, minor_ver; VAStatus va_status; pthread_t thread1; int ret; char c; int i; while ((c =getopt(argc,argv,"w:h:g:r:d:f:tcep?n:v") ) != EOF) { switch (c) { case '?': printf("putsurface <options>\n"); printf(" -g <widthxheight+x_location+y_location> window geometry\n"); printf(" -w/-h resolution of surface\n"); printf(" -r <framerate>\n"); printf(" -d the dimension of black/write square box, default is 32\n"); printf(" -t multi-threads\n"); printf(" -c test clipbox\n"); printf(" -f <1/2> top field, or bottom field\n"); printf(" -v verbose output\n"); exit(0); break; case 'g': ret = sscanf(optarg, "%dx%d+%d+%d", &win_width, &win_height, &win_x, &win_y); if (ret != 4) { printf("invalid window geometry, must be widthxheight+x_location+y_location\n"); exit(0); } else printf("Create window at (%d, %d), width = %d, height = %d\n", win_x, win_y, win_width, win_height); break; case 'r': frame_rate = atoi(optarg); break; case 'w': surface_width = atoi(optarg); break; case 'h': surface_height = atoi(optarg); break; case 'n': frame_num_total = atoi(optarg); break; case 'd': box_width = atoi(optarg); break; case 't': multi_thread = 1; printf("Two threads to do vaPutSurface\n"); break; case 'e': check_event = 0; break; case 'p': put_pixmap = 1; break; case 'c': test_clip = 1; break; case 'f': if (atoi(optarg) == 1) { printf("Display TOP field\n"); display_field = VA_TOP_FIELD; } else if (atoi(optarg) == 2) { printf("Display BOTTOM field\n"); display_field = VA_BOTTOM_FIELD; } else printf("The validate input for -f is: 1(top field)/2(bottom field)\n"); break; case 'v': verbose = 1; printf("Enable verbose output\n"); break; } } win_display = (void *)open_display(); if (win_display == NULL) { fprintf(stderr, "Can't open the connection of display!\n"); exit(-1); } create_window(win_display, win_x, win_y, win_width, win_height); va_dpy = vaGetDisplay(win_display); va_status = vaInitialize(va_dpy, &major_ver, &minor_ver); CHECK_VASTATUS(va_status, "vaInitialize"); va_status = vaCreateSurfaces(va_dpy,surface_width, surface_height, VA_RT_FORMAT_YUV420, SURFACE_NUM, &surface_id[0]); CHECK_VASTATUS(va_status, "vaCreateSurfaces"); if (multi_thread == 0) /* upload the content for all surfaces */ upload_source_YUV_once_for_all(); if (check_event) pthread_mutex_init(&gmutex, NULL); for(i = 0; i< SURFACE_NUM; i++) pthread_mutex_init(&surface_mutex[i], NULL); if (multi_thread == 1) ret = pthread_create(&thread1, NULL, putsurface_thread, (void*)drawable_thread1); putsurface_thread((void *)drawable_thread0); if (multi_thread == 1) pthread_join(thread1, (void **)&ret); printf("thread1 is free\n"); vaDestroySurfaces(va_dpy,&surface_id[0],SURFACE_NUM); vaTerminate(va_dpy); close_display(win_display); return 0; }