示例#1
0
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 {
示例#2
0
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 {