static int gvv_deliver(const frame_info_t *fi, glw_video_t *gv, glw_video_engine_t *gve) { vdpau_dev_t *vd = gv->w.glw_root->gr_be.gbr_vdpau_dev; glw_video_surface_t *s; VdpRect src_rect = { 0, 0, fi->fi_width, fi->fi_height }; int hvec[3], wvec[3]; wvec[0] = fi->fi_width; wvec[1] = 0; wvec[2] = 0; hvec[0] = fi->fi_height; hvec[1] = 0; hvec[2] = 0; VdpRect dst_rect = { 0, 0, fi->fi_width, fi->fi_height }; if(glw_video_configure(gv, gve)) return -1; glw_video_vdpau_t *gvv = gv->gv_aux; vdpau_mixer_t *vm = &gvv->gvv_vm; gv->gv_cmatrix_tgt[0] = 1.0f; /* Video mixer */ if(vm->vm_width != fi->fi_width || vm->vm_height != fi->fi_height) { VdpStatus st; vdpau_mixer_deinit(vm); st = vdpau_mixer_create(vd, vm, fi->fi_width, fi->fi_height); if(st != VDP_STATUS_OK) { TRACE(TRACE_ERROR, "VDPAU", "Unable to create video mixer"); return -1; } } if((s = glw_video_get_surface(gv, wvec, hvec)) == NULL) return -1; s->gvs_width[0] = fi->fi_width; s->gvs_height[0] = fi->fi_height; vdpau_mixer_set_color_matrix(vm, fi); if(fi->fi_interlaced) { int duration = fi->fi_duration >> 1; if(video_settings.vdpau_deinterlace_resolution_limit > 0 && fi->fi_height > video_settings.vdpau_deinterlace_resolution_limit) vdpau_mixer_set_deinterlacer(vm, 0); else vdpau_mixer_set_deinterlacer(vm, video_settings.vdpau_deinterlace); if(vm->vm_surfaces[3] != NULL) av_frame_unref(vm->vm_surfaces[3]); vm->vm_surfaces[3] = vm->vm_surfaces[2]; vm->vm_surfaces[2] = vm->vm_surfaces[1]; vm->vm_surfaces[1] = vm->vm_surfaces[0]; vm->vm_surfaces[0] = av_frame_clone(fi->fi_avframe); VdpVideoSurface past[2], present, future; past[1] = frame_to_surface(vm->vm_surfaces[3]); past[0] = frame_to_surface(vm->vm_surfaces[2]); present = frame_to_surface(vm->vm_surfaces[1]); future = frame_to_surface(vm->vm_surfaces[0]); vd->vdp_video_mixer_render(vm->vm_mixer, VDP_INVALID_HANDLE, NULL, !fi->fi_tff, 2, past, present, 1, &future, &src_rect, s->gvs_vdpau_surface, &dst_rect, &dst_rect, 0, NULL); glw_video_put_surface(gv, s, fi->fi_pts - duration, fi->fi_epoch, duration, 0, 0); if((s = glw_video_get_surface(gv, wvec, hvec)) == NULL) return -1; s->gvs_width[0] = fi->fi_width; s->gvs_height[0] = fi->fi_height; vd->vdp_video_mixer_render(vm->vm_mixer, VDP_INVALID_HANDLE, NULL, fi->fi_tff, 2, past, present, 1, &future, &src_rect, s->gvs_vdpau_surface, &dst_rect, &dst_rect, 0, NULL); } else {
void glw_video_input_vdpau(glw_video_t *gv, uint8_t * const data[], const int pitch[], const frame_info_t *fi) { struct vdpau_render_state *rs = (struct vdpau_render_state *)data[0]; vdpau_dev_t *vd = gv->w.glw_root->gr_be.gbr_vdpau_dev; vdpau_mixer_t *vm = &gv->gv_vm; glw_video_surface_t *s; int wvec[3] = {fi->fi_width}; int hvec[3] = {fi->fi_height}; VdpRect src_rect = { 0, 0, fi->fi_width, fi->fi_height }; #if 0 VdpRect dst_rect = { 0, 0, gv->gv_rwidth ?: fi->fi_width, gv->gv_rheight ?: fi->fi_height }; #else VdpRect dst_rect = { 0, 0, fi->fi_width, fi->fi_height }; #endif if(glw_video_configure(gv, &glw_video_vdpau, wvec, hvec, 4, 0)) return; if((s = glw_video_get_surface(gv)) == NULL) return; s->gvs_width = fi->fi_width; s->gvs_height = fi->fi_height; vdpau_mixer_set_color_matrix(vm, fi); if(fi->fi_interlaced) { int duration = fi->fi_duration >> 1; if(video_settings.vdpau_deinterlace_resolution_limit > 0 && fi->fi_height > video_settings.vdpau_deinterlace_resolution_limit) vdpau_mixer_set_deinterlacer(vm, 0); else vdpau_mixer_set_deinterlacer(vm, video_settings.vdpau_deinterlace); vm->vm_surface_win[3] = vm->vm_surface_win[2]; vm->vm_surface_win[2] = vm->vm_surface_win[1]; vm->vm_surface_win[1] = vm->vm_surface_win[0]; vm->vm_surface_win[0] = rs->surface; vd->vdp_video_mixer_render(vm->vm_mixer, VDP_INVALID_HANDLE, NULL, !fi->fi_tff, 2, &vm->vm_surface_win[2], vm->vm_surface_win[1], 1, &vm->vm_surface_win[0], &src_rect, s->gvs_vdpau_surface, &dst_rect, &dst_rect, 0, NULL); glw_video_put_surface(gv, s, fi->fi_pts - duration, fi->fi_epoch, duration, 0); if((s = glw_video_get_surface(gv)) == NULL) return; s->gvs_width = fi->fi_width; s->gvs_height = fi->fi_height; vd->vdp_video_mixer_render(vm->vm_mixer, VDP_INVALID_HANDLE, NULL, fi->fi_tff, 2, &vm->vm_surface_win[2], vm->vm_surface_win[1], 1, &vm->vm_surface_win[0], &src_rect, s->gvs_vdpau_surface, &dst_rect, &dst_rect, 0, NULL); } else {