static void Close(vlc_va_t *va) { vlc_va_sys_t *sys = va->sys; if (sys->context->decoder != VDP_INVALID_HANDLE) Deinit(va); vdp_release_x11(sys->vdp); av_free(sys->context); free(sys); }
static void Close(vlc_va_t *va, AVCodecContext *avctx) { vlc_va_sys_t *sys = va->sys; for (unsigned i = 0; sys->pool[i] != NULL; i++) DestroySurface(sys->pool[i]); vdp_release_x11(sys->vdp); av_freep(&avctx->hwaccel_context); free(sys); }
static int Open(vlc_object_t *obj) { filter_t *filter = (filter_t *)obj; if (filter->fmt_in.video.i_chroma != VLC_CODEC_VDPAU_VIDEO_420 && filter->fmt_in.video.i_chroma != VLC_CODEC_VDPAU_VIDEO_422 && filter->fmt_in.video.i_chroma != VLC_CODEC_VDPAU_VIDEO_444) return VLC_EGENERIC; if (!video_format_IsSimilar(&filter->fmt_in.video, &filter->fmt_out.video)) return VLC_EGENERIC; /* Check for sharpen support */ vdp_t *vdp; VdpDevice device; VdpStatus err; VdpBool ok; err = vdp_get_x11(NULL, -1, &vdp, &device); if (err != VDP_STATUS_OK) return VLC_EGENERIC; /* Weird. The decoder should be active... */ err = vdp_video_mixer_query_feature_support(vdp, device, VDP_VIDEO_MIXER_FEATURE_SHARPNESS, &ok); if (err != VDP_STATUS_OK) ok = VDP_FALSE; vdp_release_x11(vdp); if (ok != VDP_TRUE) { msg_Err(filter, "sharpening/blurring not supported by VDPAU device"); return VLC_EGENERIC; } /* Initialization */ filter_sys_t *sys = malloc(sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; filter->pf_video_filter = Sharpen; filter->p_sys = sys; config_ChainParse(filter, "sharpen-", options, filter->p_cfg); var_AddCallback(filter, "sharpen-sigma", SharpenCallback, sys); union { uint32_t u; float f; } u; u.f = vlc_to_vdp_sigma(var_CreateGetFloatCommand(filter, "sharpen-sigma")); atomic_init(&sys->sigma, u.u); return VLC_SUCCESS; }
static void pictureSys_DestroyVDPAU(picture_sys_t *psys) { vdp_output_surface_destroy(psys->vdp, psys->surface); vdp_release_x11(psys->vdp); free(psys); }
static int Open(vlc_va_t *va, AVCodecContext *ctx, const es_format_t *fmt) { VdpStatus err; VdpDecoderProfile profile; int level = fmt->i_level; if (av_vdpau_get_profile(ctx, &profile)) { msg_Err(va, "unsupported codec %d or profile %d", ctx->codec_id, fmt->i_profile); return VLC_EGENERIC; } switch (ctx->codec_id) { case AV_CODEC_ID_MPEG1VIDEO: level = VDP_DECODER_LEVEL_MPEG1_NA; break; case AV_CODEC_ID_MPEG2VIDEO: level = VDP_DECODER_LEVEL_MPEG2_HL; break; case AV_CODEC_ID_H263: level = VDP_DECODER_LEVEL_MPEG4_PART2_ASP_L5; break; case AV_CODEC_ID_H264: if ((fmt->i_profile & FF_PROFILE_H264_INTRA) && (fmt->i_level == 11)) level = VDP_DECODER_LEVEL_H264_1b; default: break; } if (!vlc_xlib_init(VLC_OBJECT(va))) { msg_Err(va, "Xlib is required for VDPAU"); return VLC_EGENERIC; } vlc_va_sys_t *sys = malloc(sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; sys->context = av_vdpau_alloc_context(); if (unlikely(sys->context == NULL)) { free(sys); return VLC_ENOMEM; } err = vdp_get_x11(NULL, -1, &sys->vdp, &sys->device); if (err != VDP_STATUS_OK) { free(sys->context); free(sys); return VLC_EGENERIC; } void *func; err = vdp_get_proc_address(sys->vdp, sys->device, VDP_FUNC_ID_DECODER_RENDER, &func); if (err != VDP_STATUS_OK) goto error; sys->context->decoder = VDP_INVALID_HANDLE; sys->context->render = func; sys->profile = profile; /* Check capabilities */ VdpBool support; uint32_t l, mb, w, h; if (vdp_video_surface_query_capabilities(sys->vdp, sys->device, VDP_CHROMA_TYPE_420, &support, &w, &h) != VDP_STATUS_OK) support = VDP_FALSE; if (!support) { msg_Err(va, "video surface format not supported: %s", "YUV 4:2:0"); goto error; } msg_Dbg(va, "video surface limits: %"PRIu32"x%"PRIu32, w, h); if (w < fmt->video.i_width || h < fmt->video.i_height) { msg_Err(va, "video surface above limits: %ux%u", fmt->video.i_width, fmt->video.i_height); goto error; } if (vdp_decoder_query_capabilities(sys->vdp, sys->device, profile, &support, &l, &mb, &w, &h) != VDP_STATUS_OK) support = VDP_FALSE; if (!support) { msg_Err(va, "decoder profile not supported: %u", profile); goto error; } msg_Dbg(va, "decoder profile limits: level %"PRIu32" mb %"PRIu32" " "%"PRIu32"x%"PRIu32, l, mb, w, h); if ((int)l < level || w < fmt->video.i_width || h < fmt->video.i_height) { msg_Err(va, "decoder profile above limits: level %d %ux%u", level, fmt->video.i_width, fmt->video.i_height); goto error; } const char *infos; if (vdp_get_information_string(sys->vdp, &infos) != VDP_STATUS_OK) infos = "VDPAU"; va->sys = sys; va->description = (char *)infos; va->pix_fmt = AV_PIX_FMT_VDPAU; va->setup = Setup; va->get = Lock; va->release = Unlock; va->extract = Copy; return VLC_SUCCESS; error: vdp_release_x11(sys->vdp); av_free(sys->context); free(sys); return VLC_EGENERIC; }
static int Open(vlc_va_t *va, AVCodecContext *avctx, enum PixelFormat pix_fmt, const es_format_t *fmt, picture_sys_t *p_sys) { if (pix_fmt != AV_PIX_FMT_VDPAU) return VLC_EGENERIC; (void) fmt; (void) p_sys; void *func; VdpStatus err; VdpChromaType type; uint32_t width, height; if (av_vdpau_get_surface_parameters(avctx, &type, &width, &height)) return VLC_EGENERIC; switch (type) { case VDP_CHROMA_TYPE_420: case VDP_CHROMA_TYPE_422: case VDP_CHROMA_TYPE_444: break; default: msg_Err(va, "unsupported chroma type %"PRIu32, type); return VLC_EGENERIC; } if (!vlc_xlib_init(VLC_OBJECT(va))) { msg_Err(va, "Xlib is required for VDPAU"); return VLC_EGENERIC; } unsigned refs = avctx->refs + 2 * avctx->thread_count + 5; vlc_va_sys_t *sys = malloc(sizeof (*sys) + (refs + 1) * sizeof (sys->pool[0])); if (unlikely(sys == NULL)) return VLC_ENOMEM; sys->type = type; sys->width = width; sys->height = height; err = vdp_get_x11(NULL, -1, &sys->vdp, &sys->device); if (err != VDP_STATUS_OK) { free(sys); return VLC_EGENERIC; } unsigned flags = AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH; err = vdp_get_proc_address(sys->vdp, sys->device, VDP_FUNC_ID_GET_PROC_ADDRESS, &func); if (err != VDP_STATUS_OK) goto error; if (av_vdpau_bind_context(avctx, sys->device, func, flags)) goto error; va->sys = sys; unsigned i = 0; while (i < refs) { sys->pool[i] = CreateSurface(va); if (sys->pool[i] == NULL) break; i++; } sys->pool[i] = NULL; if (i < avctx->refs + 3u) { msg_Err(va, "not enough video RAM"); while (i > 0) DestroySurface(sys->pool[--i]); goto error; } if (i < refs) msg_Warn(va, "video RAM low (allocated %u of %u buffers)", i, refs); const char *infos; if (vdp_get_information_string(sys->vdp, &infos) != VDP_STATUS_OK) infos = "VDPAU"; va->description = infos; va->get = Lock; va->release = NULL; va->extract = Copy; return VLC_SUCCESS; error: vdp_release_x11(sys->vdp); free(sys); return VLC_EGENERIC; }