VaapiDisplay::~VaapiDisplay() { GNASH_REPORT_FUNCTION; if (_display) { vaTerminate(_display); } }
Decode_Status VaapiDecoderBase::terminateVA(void) { INFO("base: terminate VA"); if (m_bufPool) { delete m_bufPool; m_bufPool = NULL; } if (m_VAContext != VA_INVALID_ID) { vaDestroyContext(m_VADisplay, m_VAContext); m_VAContext = VA_INVALID_ID; } if (m_VAConfig != VA_INVALID_ID) { vaDestroyConfig(m_VADisplay, m_VAConfig); m_VAConfig = VA_INVALID_ID; } if (m_VADisplay) { vaTerminate(m_VADisplay); m_VADisplay = NULL; } #ifdef ANDROID delete m_display; #else if (m_display && m_ownNativeDisplay) { XCloseDisplay(m_display); } #endif m_display = NULL; m_VAStarted = false; return DECODE_SUCCESS; }
VAApiWriter::~VAApiWriter() { clr(); if ( VADisp ) vaTerminate( VADisp ); if ( display ) XCloseDisplay( display ); }
static int create(struct gl_hwdec *hw) { GL *gl = hw->gl; struct priv *p = talloc_zero(hw, struct priv); hw->priv = p; p->current_image.buf = p->current_image.image_id = VA_INVALID_ID; p->log = hw->log; if (hw->hwctx) return -1; if (!eglGetCurrentDisplay()) return -1; if (!strstr(gl->extensions, "EXT_image_dma_buf_import") || !strstr(gl->extensions, "EGL_KHR_image_base") || !strstr(gl->extensions, "GL_OES_EGL_image") || !(gl->mpgl_caps & MPGL_CAP_TEX_RG)) return -1; // EGL_KHR_image_base p->CreateImageKHR = (void *)eglGetProcAddress("eglCreateImageKHR"); p->DestroyImageKHR = (void *)eglGetProcAddress("eglDestroyImageKHR"); // GL_OES_EGL_image p->EGLImageTargetTexture2DOES = (void *)eglGetProcAddress("glEGLImageTargetTexture2DOES"); if (!p->CreateImageKHR || !p->DestroyImageKHR || !p->EGLImageTargetTexture2DOES) return -1; p->display = create_native_va_display(gl); 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; } MP_VERBOSE(p, "using VAAPI EGL interop\n"); insane_hack(hw); if (!test_format(hw)) { destroy(hw); return -1; } hw->hwctx = &p->ctx->hwctx; return 0; }
void VaApi::finalize() { if (!VaApi::init) return; auto &dpy = VaApi::get().m_display; if (dpy) { vaTerminate(dpy); dpy = nullptr; } init = false; }
void vlc_vaapi_ReleaseInstance(struct vlc_vaapi_instance *inst) { if (atomic_fetch_sub(&inst->pic_refcount, 1) == 1) { vaTerminate(inst->dpy); if (inst->native != NULL && inst->native_destroy_cb != NULL) inst->native_destroy_cb(inst->native); free(inst); } }
OMXVideoDecoderVP9HWR::~OMXVideoDecoderVP9HWR() { LOGV("OMXVideoDecoderVP9HWR is destructed."); unsigned int i = 0; if (mVADisplay) { vaTerminate(mVADisplay); mVADisplay = NULL; } }
static void display_finalize(FFVADisplay *display) { const FFVADisplayClass * const klass = display->klass; if (display->va_display) vaTerminate(display->va_display); if (klass->close) klass->close(display); free(display->display_name); }
static void Close( vlc_va_vaapi_t *p_va ) { if( p_va->i_surface_width || p_va->i_surface_height ) DestroySurfaces( p_va ); if( p_va->i_config_id != VA_INVALID_ID ) vaDestroyConfig( p_va->p_display, p_va->i_config_id ); if( p_va->p_display ) vaTerminate( p_va->p_display ); if( p_va->p_display_x11 ) XCloseDisplay( p_va->p_display_x11 ); }
void test_terminate() { va_status = vaTerminate(va_dpy); ASSERT( VA_STATUS_SUCCESS == va_status ); status("vaTerminate\n"); if (profiles) { free(profiles); profiles = NULL; } }
~VAAPIDisplay() { if (m_va_disp) { INIT_ST; XLOCK(m_x_disp, va_status = vaTerminate(m_va_disp)); CHECK_ST; } if (m_x_disp) { m_x_disp->Sync(true); delete m_x_disp; } }
void tables_close_display(void) { pthread_mutex_lock(&display.lock); screensaver_disconnect(); #if HAVE_HWDEC if (display.va) vaTerminate(display.va); #endif // HAVE_HWDEC XFreeCursor(display.x, display.transparent_cursor); XCloseDisplay(display.x); pthread_mutex_unlock(&display.lock); pthread_mutex_destroy(&display.lock); }
void VideoDecoderVAAPIPrivate::close() { restore(); if (surface_width || surface_height) destroySurfaces(); if (config_id != VA_INVALID_ID) { vaDestroyConfig(display, config_id); config_id = VA_INVALID_ID; } if (display) { vaTerminate(display); display = 0; } if (display_x11) { XCloseDisplay(display_x11); display_x11 = 0; } }
static int create(struct gl_hwdec *hw) { if (hw->info->vaapi_ctx) return -1; if (!hw->mpgl->vo->x11 || !glXGetCurrentContext()) return -1; struct priv *p = talloc_zero(hw, struct priv); hw->priv = p; p->display = vaGetDisplayGLX(hw->mpgl->vo->x11->display); if (!p->display) return -1; p->ctx = va_initialize(p->display); if (!p->ctx) { vaTerminate(p->display); return -1; } hw->info->vaapi_ctx = p->ctx; hw->converted_imgfmt = IMGFMT_RGBA; return 0; }
void VaapiEncoderBase::cleanupVA() { if (m_display && m_context) { vaDestroyContext(m_display, m_context); m_context = VA_INVALID_ID; } if (m_display && m_config) { vaDestroyConfig(m_display, m_config); m_config = VA_INVALID_ID; } if (m_display) { vaTerminate(m_display); m_display = NULL; } if (m_xDisplay) { if (!m_externalDisplay) XCloseDisplay(m_xDisplay); m_xDisplay = NULL; } }
static void Delete( vlc_va_t *va, AVCodecContext *avctx ) { vlc_va_sys_t *sys = va->sys; (void) avctx; vlc_mutex_destroy(&sys->lock); CopyCleanCache(&sys->image_cache); vaDestroyContext(sys->hw_ctx.display, sys->hw_ctx.context_id); vaDestroySurfaces(sys->hw_ctx.display, sys->surfaces, sys->count); vaDestroyConfig(sys->hw_ctx.display, sys->hw_ctx.config_id); vaTerminate(sys->hw_ctx.display); #ifdef VLC_VA_BACKEND_XLIB XCloseDisplay( sys->p_display_x11 ); #endif #ifdef VLC_VA_BACKEND_DRM close( sys->drm_fd ); #endif free( sys ); }
struct vlc_vaapi_instance * vlc_vaapi_InitializeInstance(vlc_object_t *o, VADisplay dpy, VANativeDisplay native, vlc_vaapi_native_destroy_cb native_destroy_cb) { int major = 0, minor = 0; VA_CALL(o, vaInitialize, dpy, &major, &minor); struct vlc_vaapi_instance *inst = malloc(sizeof(*inst)); if (unlikely(inst == NULL)) goto error; inst->dpy = dpy; inst->native = native; inst->native_destroy_cb = native_destroy_cb; atomic_init(&inst->pic_refcount, 1); return inst; error: vaTerminate(dpy); if (native != NULL && native_destroy_cb != NULL) native_destroy_cb(native); return NULL; }
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; }
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; }
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; }
VdpStatus vdpDeviceDestroy(VdpDevice device) { VdpStatus err_code; VdpDeviceData *data = handle_acquire(device, HANDLETYPE_DEVICE); if (NULL == data) return VDP_STATUS_INVALID_HANDLE; if (0 != data->refcount) { // Buggy client forgot to destroy dependend objects or decided that destroying // VdpDevice destroys all child object. Let's try to mitigate and prevent leakage. traceError("warning (%s): non-zero reference count (%d). Trying to free child objects.\n", __func__, data->refcount); void *parent_object = data; handle_execute_for_all(destroy_child_objects, parent_object); } if (0 != data->refcount) { traceError("error (%s): still non-zero reference count (%d)\n", __func__, data->refcount); traceError("Here is the list of objects:\n"); struct { int cnt; int total_cnt; VdpDeviceData *deviceData; } state = { .cnt = 0, .total_cnt = 0, .deviceData = data }; handle_execute_for_all(print_handle_type, &state); traceError("Objects leaked: %d\n", state.cnt); traceError("Objects visited during scan: %d\n", state.total_cnt); err_code = VDP_STATUS_ERROR; goto quit; } // cleaup libva if (data->va_available) vaTerminate(data->va_dpy); glx_ctx_push_thread_local(data); glDeleteTextures(1, &data->watermark_tex_id); glBindFramebuffer(GL_FRAMEBUFFER, 0); destroy_shaders(data); glx_ctx_pop(); glx_ctx_lock(); glXMakeCurrent(data->display, None, NULL); glx_ctx_unlock(); glx_ctx_unref_glc_hash_table(data->display); handle_xdpy_unref(data->display_orig); handle_expunge(device); pthread_mutex_destroy(&data->refcount_mutex); free(data); GLenum gl_error = glGetError(); if (GL_NO_ERROR != gl_error) { traceError("error (%s): gl error %d\n", __func__, gl_error); err_code = VDP_STATUS_ERROR; goto quit_skip_release; } return VDP_STATUS_OK; quit: handle_release(device); quit_skip_release: return err_code; }
VaapiDisplay::~VaapiDisplay() { if (!DynamicPointerCast<NativeDisplayVADisplay>(m_nativeDisplay)) { vaTerminate(m_vaDisplay); } }
int vaapi_exit(void) { VAAPIContext * const vaapi = vaapi_get_context(); unsigned int i; if (!vaapi) return 0; #if USE_GLX if (display_type() == DISPLAY_GLX) vaapi_glx_destroy_surface(); #endif destroy_buffers(vaapi->display, &vaapi->pic_param_buf_id, 1); destroy_buffers(vaapi->display, &vaapi->iq_matrix_buf_id, 1); destroy_buffers(vaapi->display, &vaapi->bitplane_buf_id, 1); destroy_buffers(vaapi->display, vaapi->slice_buf_ids, vaapi->n_slice_buf_ids); if (vaapi->subpic_flags) { free(vaapi->subpic_flags); vaapi->subpic_flags = NULL; } if (vaapi->subpic_formats) { free(vaapi->subpic_formats); vaapi->subpic_formats = NULL; vaapi->n_subpic_formats = 0; } if (vaapi->image_formats) { free(vaapi->image_formats); vaapi->image_formats = NULL; vaapi->n_image_formats = 0; } if (vaapi->entrypoints) { free(vaapi->entrypoints); vaapi->entrypoints = NULL; vaapi->n_entrypoints = 0; } if (vaapi->profiles) { free(vaapi->profiles); vaapi->profiles = NULL; vaapi->n_profiles = 0; } if (vaapi->slice_params) { free(vaapi->slice_params); vaapi->slice_params = NULL; vaapi->slice_params_alloc = 0; vaapi->n_slice_params = 0; } if (vaapi->slice_buf_ids) { free(vaapi->slice_buf_ids); vaapi->slice_buf_ids = NULL; vaapi->n_slice_buf_ids = 0; } if (vaapi->subpic_image.image_id != VA_INVALID_ID) { vaDestroyImage(vaapi->display, vaapi->subpic_image.image_id); vaapi->subpic_image.image_id = VA_INVALID_ID; } for (i = 0; i < ARRAY_ELEMS(vaapi->subpic_ids); i++) { if (vaapi->subpic_ids[i] != VA_INVALID_ID) { vaDestroySubpicture(vaapi->display, vaapi->subpic_ids[i]); vaapi->subpic_ids[i] = VA_INVALID_ID; } } if (vaapi->surface_id) { vaDestroySurfaces(vaapi->display, &vaapi->surface_id, 1); vaapi->surface_id = 0; } if (vaapi->context_id) { vaDestroyContext(vaapi->display, vaapi->context_id); vaapi->context_id = 0; } if (vaapi->config_id) { vaDestroyConfig(vaapi->display, vaapi->config_id); vaapi->config_id = 0; } if (vaapi->display) { vaTerminate(vaapi->display); vaapi->display = NULL; } free(vaapi_context); return 0; }
VaapiDisplay::~VaapiDisplay() { vaTerminate(m_vaDisplay); }
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; }
VAApiWriter::~VAApiWriter() { clr(); if ( VADisp ) vaTerminate( VADisp ); }